2013-02-14 2 views
0

이중 연결 목록의 전체 복사본을 만드는 데 문제가 있습니다. 이것은 숙제 임으로, 내가 이해하지 못하는 작업 코드를 얻는 대신 내 코드가 왜 작동하지 않는지 알고 싶습니다. 나는 위의 인터페이스를 사용하는 데 필요한하고이중 연결 목록의 전체 복사본

#ifndef TEXTANALYZER_H 
#define TEXTANALYZER_H 

#include <iostream> 
#include <string> 

using namespace std; 

class TextAnalyzer { 
private: 

/* 
* Class: Node 
* 
* This class represents a node in a sorted doubly linked list that stores a 
* list of words and their frequency of occurrence. 
*/ 
class Node { 
public: 
    string word; 
    int wordFrequency; 
    Node* previous; 
    Node* next; 

    Node(const string& word, 
     const int wordFrequency, 
     Node* const previous, 
     Node* const next) 
    : word(word), 
     wordFrequency(wordFrequency), 
     previous(previous), 
     next(next) 
    {} 
}; // end ListNode 
/*********************************************************************/ 

Node* head; 
Node* tail; 


/* 
* Releases all the memory allocated to the list. 
*/ 
void releaseNodes(); 

/* 
* Makes a deep copy of the object. 
*/ 
void copyNodes(Node* const copyHead); 

/* 
* Returns a populated Node. 
* Throws a bad_alloc exception if memory is not allocated. 
*/ 
Node* createNode(const string& word, 
       const int wordFrequency, 
       Node* const previous, 
       Node* const next); 

public: 
/* 
* Initializes head and tail, each to a dymmy node. 
*/ 
TextAnalyzer(); 

/* 
* Makes a deep copy of the object passed in. 
* Calls copyNodes() to do the actual work.  
*/ 
TextAnalyzer(const TextAnalyzer& copyObject); 

/* 
* Releases all the memory allocated to the object. 
* Calls the releaseNodes() method to do the actual work. 
*/ 
~TextAnalyzer(); 

/* 
* Makes a deep copy of the rhs object. 
*/ 
TextAnalyzer operator =(const TextAnalyzer& assignObject); 

/* 
* Inserts the word in a sorted order into the list. 
* 
* If no Node exists with that initial character, one is added in 
* sorted order. If one does exist (same word), then the word frequency 
* of that word is incremented by one. 
*/ 
void insertWord(const string& word); 

/* 
* Returns a count of all the words in the list. 
*/ 
int wordCount() const; 

/* 
* Returns a count of all the words with the initial character. 
*/ 
int wordCountWithInitialCharacter(const char startsWith); 

/* 
* Returns a description of the object. The string is formatted as: 
* [A words:] 
*  [<word>(<count>)] 
*  [<word>(<count>)] 
*  ... 
* 
* [B words:] 
*  [<word>(<count>)] 
*  [<word>(<count>)] 
*  ... 
* 
*... 
*/ 
string toString() const; 

}; 

#endif 

: 여기

#include "textAnalyzer.h" 
#include <string> 
#include <iostream> 
#include <sstream> 

TextAnalyzer::Node* TextAnalyzer::createNode(const string& word, const int wordFrequency, 
Node* const previous, Node* const next) 
{ 
return new Node(word, wordFrequency, previous, next); 
} 
void TextAnalyzer::releaseNodes() 
{ 
Node* del = tail; 

while(tail != NULL) 
{ 
    tail = tail->previous; 
    tail->next = del; 
    delete del; 
    del = tail; 
} 

delete [] head; 
delete [] tail; 

head = tail = del = NULL; 
} 

void TextAnalyzer::copyNodes(Node* const copyHead) 
{ 
head = new Node(*copyHead); 
Node* iter = head->next; 

for(Node* np = copyHead->next; np != NULL; np = np->next) 
{ 
    iter->next = new Node(*np); 
    iter = iter->next; 
} 

iter = NULL; 
} 

TextAnalyzer::TextAnalyzer():head(createNode("0",0,NULL,NULL)),tail(head) 
{} 

TextAnalyzer::TextAnalyzer(const TextAnalyzer& copyObject) 
{ 
copyNodes(copyObject.head); 
} 

TextAnalyzer::~TextAnalyzer() 
{ 
releaseNodes(); 
} 

TextAnalyzer TextAnalyzer::operator=(const TextAnalyzer& assignObject) 
{ 
return TextAnalyzer(assignObject); 
} 

void TextAnalyzer::insertWord(const string& word) 
{ 
Node* iter = head->next; 

while(iter != NULL) 
{ 
    if(iter->word == word) 
     iter->wordFrequency++; 
    else if(iter->word[0] == word[0] && iter->next != NULL) 
    { 
     Node* temp = iter->next; 
     iter->next = createNode(word, 1, iter, temp); 
     iter = iter->next; 
     temp->previous = iter; 

     temp = NULL; 
    } 
    else if(iter->word[0] == word[0] && iter->next == NULL) 
    { 
     iter = createNode(word, 1, tail, NULL); 
     tail = iter; 
    } 
    else 
     iter = iter->next; 
} 

iter = NULL; 
} 

int TextAnalyzer::wordCount() const 
{ 
Node* iter = head->next; 
int count = 0; 

while(iter != NULL) 
    count++; 

return count; 
} 

int TextAnalyzer::wordCountWithInitialCharacter(const char startsWith) 
{ 
Node* iter = head->next; 
int count = 0; 

for(int i = 0; i < wordCount(); i++) 
{ 
    if(startsWith == iter->word[0]) 
     count++; 

    iter->previous = iter; 
    iter = iter->next; 
} 

iter = NULL; 

return count; 
} 

string TextAnalyzer::toString() const 
{ 
Node* iter = head->next; 
string desc = "List of words: \n"; 
ostringstream convert; 

for(int i = 0; i < wordCount(); i++) 
{ 
    convert << iter->word[0] << " words:\n" 
      << iter->word << "(" 
      << iter->wordFrequency 
      << ")\n"; 
    iter->previous = iter; 
    iter = iter->next; 
} 

iter = NULL; 

return desc + convert.str(); 
} 

는 인터페이스 :

여기 내 클래스입니다. 내 문제는 내 복사본 생성자에 "개체에 호환되지 않는 한정자가 있습니다"라는 오류가 있거나 이와 유사한 것입니다. copyObject이 상수이기 때문에 이것이라고 가정합니다. 그러나, 나는 그렇지 않으면 어떻게 해야할지에 관해서 잃어 버렸습니다. 누군가 제가 여기서 무엇을 놓치고 있는지 말해 줄 수 있습니까? 나는 C++에 상당히 익숙하지 만 자바에 대한 경험이 많기 때문에 혼란 스러울 수 있습니다.

편집 : 응답

감사합니다. 나는 어떻게 성공적으로 딥 카피를 할 것인지를 알아 내려고했다. 지금까지 완료 한 내용을 보여주기 위해 코드를 업데이트했습니다. 이제 코드를 컴파일 했으므로 새로운 오류가 발생했습니다. "처리되지 않은 예외 0xc0000005"때마다 그것을 실행합니다. 나는 그것을 봤 거든 그것을 null 포인터를 dereference 시도하여 오류가 있다고 생각합니다. 디버거는 내 releaseNodes() 메서드에서 throw 된 것을 보여줍니다. 디버거가 오류가 유래라고하는 위

void TextAnalyzer::releaseNodes() 
{ 
Node* del = tail; 

while(tail != NULL) 
{ 
    tail = tail->previous; //error on this line 
    tail->next = del; 
    delete del; 
    del = tail; 
} 

delete [] head; 
delete [] tail; 

head = tail = del = NULL; 
} 

이 보여주는 주석이 내 releaseNodes() 방법이다. 이드는 C++을 처음 접한 이래로 나머지 코드가 작동하는지보고 싶습니다. 내 논리가 다른 곳에서도 결함이있을 가능성이 높습니다. 불행히도이 오류가 해결 될 때까지는 아무 것도 테스트 할 수 없습니다. 나는 아직도 그것을 일으키는 원인이 될 수있는 것을 찾으려고 노력하면서 나의 코드를 추적하고있다. 누군가가 올바른 방향으로 나를 가리킬 수 있다면 그것은 인정 될 것이다.

+0

괜찮습니다. 그게 좋은 지적 여기에 : http://stackoverflow.com/questions/890535/what-is-the-difference-between-char-const-and-const-char 그냥 본 적이 전에! – v01pe

+1

문제를 직접 파악하는 것은 아주 가깝습니다. 그것은 실제로'copyObject'가 const이기 때문입니다. 올바른 인스턴스에서'copyNodes()'메소드를 호출 하시겠습니까? – vhallac

+1

... 'copyNodes'에 인수를 넘겨서는 안됩니까? –

답변

0

나는 그냥 머리에 다음 포인터 새로운 노드 객체를 할당하고

void TextAnalyzer::copyNodes(Node* const copyHead) 
{ 
    head->next = new Node(*copyHead); 
} 

을 말한다 곳이 라인의 있으리라 믿고있어. 근본적으로 당신은 단지 하나의 노드, 노드를 따르는 노드를 복사하고 전체 목록을 복사하지는 않습니다. while 루프를 사용하여 releaseNode에서 수행해야하는 작업에 대한 올바른 아이디어를 얻었습니다.

복사 생성자에서 잘못 호출하는 경우도 있습니다. 정의에 매개 변수를 지정했지만 생성자에서 아무 것도 허용하지 않는 매개 변수를 호출했습니다.

+0

꼭 그런 것은 아닙니다.코드에서 복사 생성자가 보이지 않지만 전체 목록의 복사본을 만들 수 있습니다 (코드를 짧게 유지하기 위해 반복적으로조차도 가능). – vhallac

+0

이 파일은 cpp 파일의 마지막 세 줄입니다. OP는 copyNodes (Node * const head);를 호출하는 것으로 가정하는 copyNodes()를 호출합니다. – Goyatuzo

+0

나는'Node' 클래스의 복사 생성자를 의미했습니다. 그것은 다른 노드의 데이터로 데이터를 초기화하고, 다른 노드의'next'의 새로운 인스턴스를 생성하고,이 새로운 객체를'next'에 연결합니다 (그리고'previous'를 갱신하는 것을 잊지 마십시오). 딥 카피를하기위한 약 4 줄의 코드. – vhallac

관련 문제