2016-11-10 2 views
1

Ich habe eine Datensackstruktur erstellt. Ich lese den Text einer Datei und füge jedes Wort in einen Knoten ein und inkrementiere dann die Zählung, wenn dort identische Zeichenfolgen vorhanden sind. Aber mein Problem ist, ich möchte nur eine Zeichenfolge der identischen Zeichenfolgen ausgeben und die Anzahl der Male, die es verwendet wurde. Aber wenn ich meine Entfernungsfunktion verwende, wird alles in meiner Datei entfernt, und wenn ich sie nicht verwende, erhalte ich die unten gezeigte Ausgabe. Ich weiß nicht, was ich falsch mache, gibt es eine Möglichkeit, doppelte Strings nicht auszugeben?Entfernen bestimmter Knoten

ofstream output; 
struct BagNode 
{ 
    string dataValue; 
    string dataCopy; 
    int dataCountCopy; 
    int dataCount; 
    BagNode * next; 
}; 
class Bag{ 
private: 

BagNode * head; 

public: 

Bag() 
{ 
    head = NULL; 

} 
void insert(string v) 
{ 
    if(head == NULL){ //empty list 
     head = new BagNode; 
     removePunct(v); 
     head->dataValue = v; 
     transform(v.begin(), v.end(), v.begin(), ::tolower); 
     head->dataCopy = v; 
     head->next = NULL; 

    } 
    else 
    { 
      BagNode * n = new BagNode;  // new node 
      removePunct(v); 
      n->dataValue = v; 
      transform(v.begin(), v.end(), v.begin(), ::tolower); 
      n->dataCopy = v; 
      BagNode * current = head;   //for traversal 
      //current = head; 
      n->dataCount = 0; 
       if(current->dataCopy > v) 
       {      
        n->next = head; 
        head = n; 
       } 
       else{   //mid and tail insert 
        while(current->next && current->next->dataCopy < v) 
        { 
         current = current->next; 
        } 
        n->next = current->next; 
        current->next = n; 

       } 

    } 
    BagNode * check = new BagNode; 
    for(check = head; check->next != NULL; check = check->next) 
    { 
     if(check->dataCopy == v)//isSame(check->dataValue, v)) 
     { 
      check->dataCount++; 
     } 

    } 

} 
bool remove(string v) //bool 
{ 
    bool status; 
    if(head == NULL){ 
     status = false; 
    } 
    else if(head->dataCopy > v) 
    {//(head->dataValue > v){ 
     status = false; 
    } 
    else if(head->dataCopy == v) 
    { 
     BagNode * t = head; 
     head = head->next; 
     delete t; 
     status = true; 
    } 
    else//general case 
    { 
     BagNode * current = head; 
     while(current->next && current->next->dataCopy < v){ 
      current = current->next; 
     } 
     if(current->next == NULL) 
     { 
      status = false; 
     } 
     else if(current->next->dataCopy == v) //found it 
     { 
      BagNode *t = current->next; 
      current->next = current->next->next; 
      delete t; 
      status = true; 
     } 
     else 
     { 
      status = false; 
     } 
    } 
    return status; 
} 
void traverse() 
{ 
    BagNode * current; 

    current = head; 
    while(current) 
    { 
      output << current->dataValue << " (" << current->dataCount << ")" << " "; 
      current = current->next; 

    } 
    cout << endl; 
} 

Output: 10Annette (1) 1805 (1), 7 (1), a (1) a (2) a (3) a (4) a (5) a (6) All (1) all (2) ein (1) und (1) und (2) und (3) und (4) und (5) und (6) und (10) und (7)

if(!inputFile) 
    { 
     cout << "Could Not Open " << fileName << " File" << endl; 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     while(inputFile >> text) 
     { 
      theBag.insert(text); 

     } 
     cout << "Processing File Complete" << endl; 
     cout << "Please Enter An Output File Name: "; 
     getline(cin,outputFilename); 
     output.open(outputFilename); 
     theBag.traverse(); 
     theBag.remove(text); 
     inputFile.close(); 
     output.close(); 
    } 
+0

@RawN Ok, es ist da oben. Danke – Thompson

+1

Die blöd-einfache Art, die wahrscheinlich die Hölle aus deinem Lehrer beleidigen wird, ist 'std :: map strings;' Mit ihr kannst du 'strings [stringIJustParsed] ++;' und praktisch alle von der Arbeit ist getan. Die Map erzeugt ein neues 'int' für' stringIJustParsed' und Null initialisiert es oder erhält ein bereits existierendes 'int' wenn' stringIJustParsed' bereits bekannt ist. Neu oder alt 'int', der' int' wird inkrementiert und liefert Ihren Zähler. – user4581301

+0

@ user4581301 also für meine dataCount brauche ich es wirklich nicht? – Thompson

Antwort

1

Wenn Sie hier in Ihrer Einfügefunktion nachsehen, berühren Sie tatsächlich jeden Knoten mit diesem Wert. Also, wenn v = "And" jedes einzelne "Und" -Wort bekommt, wird seine Datenanzahl inkrementiert. Dadurch erhalten Sie die korrekte Anzahl eines Wortes auf jedem Knoten.

for(check = head; check->next != NULL; check = check->next) 
{ 
    if(check->dataCopy == v)//isSame(check->dataValue, v)) 
    { 
     check->dataCount++; 
    } 
} 

Scheint wie Sie Ihren Einsatz mit diesem Verhalten viel einfacher machen könnten.

+0

Wenn das, was Sie sagen, ist "Der beste Weg, keine Wiederholungen zu haben ist, keine Duplikate hinzuzufügen." Sie sind dran, aber Ihrem Beispiel fehlt ein Teil der Einfügelogik von OP. – user4581301

+0

Ja, meine Antwort ist absichtlich nicht Überarbeitung der Hausaufgabenlösung. Thompson hat bereits die Einfügung herausgefunden, dass sie nur ein wenig mit dem Debuggen stecken bleiben, warum ihr Programm so handelt, wie es ist. Das kann frustrierend sein und ich erinnere mich an keine Klassen zum Debuggen ;-) – snowballhg