2017-08-23 3 views
0

Hallo allerseits, das ist mein erstes Mal in Stackoverflow. Ich habe eine Frage bezüglich des Zählens des Auftretens von Wörtern in einer Textdatei mit C++. Das ist bisher mein Code. Ich muss eine Array-Struktur des Index des Wortes und des Zählers jedes Wortes erstellen und dann alle in einem AVL-Baum speichern. Nachdem ich die Datei geöffnet und ein Wort gelesen habe, suche ich im avl tree oder trie. Wenn es vorhanden ist, verwenden Sie den Index des Knotens, um das Cnt des Wortes zu erhöhen. Wenn es nicht dort ist, füge es dem Wortarray hinzu und lege seine Position in die nächste Struktur und lege die Strukturposition in die Avl-Struktur. Außerdem habe ich die Struktur Cnt auf 1 gesetzt. Das Problem, das ich jetzt habe, ist anscheinend, dass mein Programm die Zählung nicht richtig verarbeitet, daher druckt es nur 0 aus. Bitte gib mir eine Empfehlung, wie ich den Fehler beheben kann. Bitte finden meinen Code unten:Verwenden eines Arrays der Struktur, die die Anzahl des Auftretens eines Wortes in einer Textdatei zählt C++

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cstdlib> 
#include <cstring> 
#include <ctype.h> 
#include <stdio.h> 
#include <string> 
#include <cctype> 
#include <stdlib.h> 
#include <stdbool.h> 
using namespace std; 

struct Node* insert(struct Node* node, int key) ; 
void preOrder(struct Node *root) ; 
void removePunct(char str[]); 
int compareWord(char word1[], char word2[]); 

struct Stats { 
    int wordPos, wordCnt; 
}; 
Stats record[50000]; 
int indexRec = 0; 
char word[50000*10] ; 
int indexWord = 0; 

int main() { 
    ifstream fin; 
    string fname; 
    char line[200], wordArray[500000]; 

    cout << "Enter the text file name:" << endl; 
    cin >> fname; 
    fin.open(fname.c_str()); 
    if (!fin) { 
     cerr << "Unable to open file" << endl; 
     exit(1); 
    } 
    struct Node *root = NULL; 
    while (!fin.eof() && fin >> line) { //use getline 
     for(int n=0,m=0; m!=strlen(line); m+=n) { 
      sscanf(&line[m],"%s%n",word,&n); 
      removePunct(word); 
      //strcpy(&wordArray[indexWord],word); 
      int flag = compareWord(wordArray, word); 
      if(flag==-1) { 
       strcpy(&wordArray[indexWord],word); 
       record[indexRec].wordPos = indexWord; 
       record[indexRec].wordCnt = 1; 
       root = insert(root, record[indexRec].wordPos); 
       indexWord+=strlen(word)+1; 
       // indexes of the word array 
       indexRec++; 
       cout << wordArray[indexWord] << " "; 
      } else 
       record[flag].wordCnt++; 

      cout << record[indexRec].wordCnt; 
      cout << endl; 

     } 
     /*for(int x = 0; x <= i; x++) 
     { 
      cout << record[x].wordPos << record[x].wordCnt << endl; 
     }*/ 

    } 

    fin.close(); 
    return 0; 

} 

void removePunct(char str[]) { 
    char *p; 
    int bad = 0; 
    int cur = 0; 
    while (str[cur] != '\0') { 
     if (bad < cur && !ispunct(str[cur]) && !isspace(str[cur])) { 
      str[bad] = str[cur]; 
     } 
     if (ispunct(str[cur]) || isspace(str[cur])) { 
      cur++; 
     } else { 
      cur++; 
      bad++; 
     } 
    } 
    str[bad] = '\0'; 
    for (p= str; *p!= '\0'; ++p) { 
     *p= tolower(*p); 
    } 
    return; 
} 
int compareWord(char word1[], char word2[]) { 
    int x = strcmp(word1, word2); 
    if (x == 0) return x++; 
    if (x != 0) return -1; 
} 

struct Node { 
    int key; 
    struct Node *left; 
    struct Node *right; 
    int height; 
}; 

// A utility function to get maximum of two integers 
int max(int a, int b); 

// A utility function to get height of the tree 
int height(struct Node *N) { 
    if (N == NULL) 
     return 0; 
    return N->height; 
} 

// A utility function to get maximum of two integers 
int max(int a, int b) { 
    return (a > b)? a : b; 
} 

/* Helper function that allocates a new node with the given key and 
    NULL left and right pointers. */ 
struct Node* newNode(int key) { 
    struct Node* node = (struct Node*) 
         malloc(sizeof(struct Node)); 
    node->key = key; 
    node->left = NULL; 
    node->right = NULL; 
    node->height = 1; // new node is initially added at leaf 
    return(node); 
} 

// A utility function to right rotate subtree rooted with y 
// See the diagram given above. 
struct Node *rightRotate(struct Node *y) { 
    struct Node *x = y->left; 
    struct Node *T2 = x->right; 

    // Perform rotation 
    x->right = y; 
    y->left = T2; 

    // Update heights 
    y->height = max(height(y->left), height(y->right))+1; 
    x->height = max(height(x->left), height(x->right))+1; 

    // Return new root 
    return x; 
} 

// A utility function to left rotate subtree rooted with x 
// See the diagram given above. 
struct Node *leftRotate(struct Node *x) { 
    struct Node *y = x->right; 
    struct Node *T2 = y->left; 

    // Perform rotation 
    y->left = x; 
    x->right = T2; 

    // Update heights 
    x->height = max(height(x->left), height(x->right))+1; 
    y->height = max(height(y->left), height(y->right))+1; 

    // Return new root 
    return y; 
} 

// Get Balance factor of node N 
int getBalance(struct Node *N) { 
    if (N == NULL) 
     return 0; 
    return height(N->left) - height(N->right); 
} 

// Recursive function to insert key in subtree rooted 
// with node and returns new root of subtree. 
struct Node* insert(struct Node* node, int key) { 
    /* 1. Perform the normal BST insertion */ 
    if (node == NULL) 
     return(newNode(key)); 

    if (key < node->key) 
     node->left = insert(node->left, key); 
    else if (key > node->key) 
     node->right = insert(node->right, key); 
    else // Equal keys are not allowed in BST 
     return node; 

    /* 2. Update height of this ancestor node */ 
    node->height = 1 + max(height(node->left), 
          height(node->right)); 

    /* 3. Get the balance factor of this ancestor 
      node to check whether this node became 
      unbalanced */ 
    int balance = getBalance(node); 

    // If this node becomes unbalanced, then 
    // there are 4 cases 

    // Left Left Case 
    if (balance > 1 && key < node->left->key) 
     return rightRotate(node); 

    // Right Right Case 
    if (balance < -1 && key > node->right->key) 
     return leftRotate(node); 

    // Left Right Case 
    if (balance > 1 && key > node->left->key) { 
     node->left = leftRotate(node->left); 
     return rightRotate(node); 
    } 

    // Right Left Case 
    if (balance < -1 && key < node->right->key) { 
     node->right = rightRotate(node->right); 
     return leftRotate(node); 
    } 

    /* return the (unchanged) node pointer */ 
    return node; 
} 
void preOrder(struct Node *root) { 
    if(root != NULL) { 
     printf("%d ", root->key); 
     preOrder(root->left); 
     preOrder(root->right); 
    } 
} 
+3

Gibt es einen bestimmten Grund, nicht einfach eine 'std :: map '? – Frank

+1

Sieht so aus, als lernst du C und nicht C++. Funktionen wie 'removePunct' können mit nur 2 Zeilen C++ - Code geschrieben werden. – PaulMcKenzie

+0

[Hier ist ein Beispiel] (https://www.ideone.com/nNtPD2) – PaulMcKenzie

Antwort

0

Ein Problem (Ich kann nicht sehen, ob dies das einzige Problem ist) ist, dass Sie Code wie diesen haben, alle Zwischenleitungen zu löschen:

record[indexRec].wordCnt = 1; 
if find word fails 
    indexRec++; 
cout << record[indexRec].wordCnt; 

Also, wenn Sie habe ein neues Wort (wenn ich den Code richtig verstanden habe!), druckst du den nächsten Datensatz aus. Ein Update wäre:

if (flag==-1) 
    cout << record[indexRec-1].wordCnt; 
else 
    cout << record[indexRec].wordCnt; 

Es gibt viele andere Fragen, wie compareWord() ist sehr falsch, sollten Sie entscheiden, ob Sie wirklich verwenden C wollen ++ oder C mit std::cout, die Datei Code-Lese ungerade ist, Sie schließen sowohl C- als auch C++ - Versionen von Standardheadern usw. ein, aber das sind Probleme für eine andere Frage!

Verwandte Themen