2014-10-03 91 views
1

我正在编程一个双向链表,其中我从给定文件中读取字符串。 因此,我编写了一个名为Node的类,其中存储了一个字符串(读取字)以及字长和其他参数的一些整数。计数列表元素

当我读取所有字符串形成文件后,我打开第二个文件,并再次读出每个单词,并将该单词与链接列表中的字符串进行比较。之后,我将每个找到的单词存储在结果文件中。

现在我想显示找到的词有它的文本位置的用户,例如:

“上找到在thext文件中的200处字”

因此我创建了一个计数器,每创建一个新节点就增加一个计数器。我现在的问题是,我的计数器只是统计了整个创建了多少个节点。所以我只看到创建了大约56000个节点,但我无法存储节点的编号。

我在做什么错?

编辑:我没有尝试减少计数器,因为我从不删除一个节点。 这里是我完整的代码

#include <iostream> 
#include <string> 
#include <stdio.h> 
#include <fstream> 
#include <cstring> 

using namespace std; 
class Word 
{ 
    public: 
    Word (string inputstring = 0, int b = 0, int c = 0, int l = 0, Word *n = 0, Word *p = 0) : word (inputstring), book (b), chapter (c), length (l), next (n), prev (p) 
    { 
     ++counter; 
    } 
    int book; 
    int chapter; 
    int length; 
    string word; 
    Word *next; 
    Word *prev; 

    static size_t howMany() 
    { 
     return counter; 
    } 

    private: 
     static size_t counter; 
}; 

size_t Word::counter; 

int main() 
{ 
    string inputstring = "empty"; 
    string compare = "empty"; 
    int l1 = 0; 
    int book = 0; 
    int chapter = 0; 
    int count = 0; 
    Word *p = 0; 
    Word *x = 0; 
    Word *start = 0; 

    ifstream file; 
    file.open("Beispieltext.txt"); 

    ofstream outfile; 

    if (!file) cout << ("can't open input file"); 
    else   cout << "File: Beispieltext.txt open\n"; 

    // create nodes 
    while (file >> inputstring) 
    { 
     l1 = (int)inputstring.length(); 

     if ((!(inputstring[0] >= 'A' && inputstring[0] <= 'Z')) && (!(inputstring[0] >= 'a' && inputstring[0] <= 'z'))) inputstring = inputstring.substr(1,l1--); // l1-- reduce length 
     while ((!(inputstring[l1-1] >= 'A' && inputstring[l1-1] <= 'Z')) && (!(inputstring[l1-1] >= 'a' && inputstring[l1-1] <= 'z'))) inputstring = inputstring.substr(0,--l1); // --l1 go till n-1 

     // book? 
     if (std::strncmp(inputstring.data(), "BOOK", 4) == 0) ++book, chapter = 0/*, cout << "\nBook Nr.: " << book << "\n"*/; 

     // Chapter? 
     if (std::strncmp(inputstring.data(), "CHAPTER", 7) == 0) ++chapter/*, cout << "chapter: " << chapter << "\n"*/; 

     if (p == NULL) 
     { 
      p = new Word (inputstring); 
     } else 
     { 
      x = new Word (inputstring, book, chapter, l1, 0, p); 
      p->next = x; 
      p = x; 
     } 
    } 
    file.close(); 
    cout << "File: Beispieltext.txt closed!\n"; 

    // n...0 
    for (; p; p = p->prev) start = p; // go to start 

    // Open compare file 1 
    file.open("Suchbegriffe_1.txt"); 
    if (!file) cout << "Can't open compare file!\n"; 
    else  cout << "File: Suchbegriffe.txt open!\n"; 

    // Open result file 1 
    outfile.open("Result_1.txt"); 
    if(!outfile) cout << "Can't open Result_1.txt file!\n"; 
    else  cout << "File: Result_1.txt open!\n"; 

    while (file >> compare) 
    { 
     l1 = (int)compare.length(); 
     // Search 
     x = start; 
     // 0...n go to end 
     for (; x; x = x->next) 
     { 
      if (l1 == x->length) 
      { 
       if (compare == x->word) 
       { 
        outfile << "Word: " << compare << " found in book Nr.: " << x->book << ", chapter: " << x->chapter << "!\n"; 
        outfile << "Word: " << compare << " is the " << x->howMany() << " Word in the book.\n"; 
        count++; 
       } 
      } 
     } 
     outfile << "Word: " << compare << ", " << count << "x found!\n"; 
     count = 0; 
    } 
    file.close(); 
    cout << "File: Suchbegriffe_1.txt closed!\n"; 
    outfile.close(); 
    cout << "File: Result.txt closed!\n"; 

    // Open compare file 2 
    file.open("Suchbegriffe_2.txt"); 
    if (!file) cout << "Can't open compare file!\n"; 
    else  cout << "File: Suchbegriffe.txt open!\n"; 

    // Open result file 2 
    outfile.open("Result_2.txt"); 
    if (!outfile) cout << "Can't open Result_2 file!\n"; 
    else  cout << "File: Result_2.txt open!\n"; 

    while (file >> compare) 
    { 
     l1 = (int)compare.length(); 

     // Search 
     x = start; 
     // 0...n go to end 
     for (; x; x = x->next) 
     { 
      if (l1 == x->length) 
      { 
       if (compare == x->word) 
       { 
        outfile << "Word: " << compare << " found in book Nr.: " << x->book << ", chapter: " << x->chapter << "!\n"; 
        count++; 
       } 
      } 
     } 
     outfile << "Word: " << compare << ", " << count << "x found!\n"; 
     count = 0; 
    } 
    file.close(); 
    cout << "File: Suchbegriffe_2.txt closed!\n"; 

    outfile.close(); 
    cout << "File: Result_2.txt closed!\n"; 
} 
+0

请提供其余的代码(并正确格式化),而不是指望人们填写空格。 – 2014-10-03 10:49:16

+0

你是否试图在析构函数中减少计数器? – Jepessen 2014-10-03 10:49:16

+0

@Jepessen,这不会改变每个节点共享单个全局计数器的事实,因此不可能为每个节点返回不同的ID – 2014-10-03 10:51:42

回答

2

我现在的问题是我的计数器只是计算多少节点在整个创建。

是的,因为您有一个单一的全局计数器来计算创建的节点。

所以我只看到有大约56000个节点的创建,但我不能存储节点的数量。

如果你想为每个节点指定一个不同的数字,那么你不能在一个地方存储一个数字,并期望它有几个不同的值!

您需要

  • 要么商店中的每个节点作为成员变量,而不是一个静态变量的数字(但要确保你让他们正确的,如果节点被添加或从一开始就删除或列表的中间,如果你打算在程序中一次有两个列表,请确保列表中的第一个节点具有数字0,即它必须是该列表中的数字不只是全局计数器)

  • ,要简单得多,只要保留一个计数器,就可以遍历列表并为每个看到的节点增加一个计数器。你已经在计算匹配词的数量,为什么你不能只保留所有检查词的总数,包括不匹配?

例如:

​​

注意,我宣布环路(而不是在函数的顶部),内部变量和不打扰检查字长,因为比较std::string已经这样做是。为什么你甚至将这个长度存储在Word类中? x->word.length()告诉你的长度,你不需要明确地存储它。

而且,这太疯狂了:

for (; p; p = p->prev) start = p; // go to start 

这向后穿过一个大名单,找到开始......刚刚成立开始,当你分配的第一个节点,并保持它!

x = new Word (inputstring, book, chapter, l1, 0, p); 
    if (!start) 
     start = x; // remember the start 
    p->next = x; 
    p = x; 
0

我建议你在结果文件中存储一个整数值和你找到的单词。并在打印结果时显示它。

或者您可以使用节点类中的位置变量来确定它的位置。

0

快速修复:

class Word 
{ 
    public: 
    Word (string inputstring = 0, int b = 0, int c = 0, int l = 0, Word *n = 0, Word *p = 0) 
     : word (inputstring), book (b), chapter (c), length (l), next (n), prev (p) 
    { 
     currCont = ++counter; 
    } 
    int book; 
    int chapter; 
    int length; 
    string word; 
    Word *next; 
    Word *prev; 
    int currCont; 

    size_t howMany() 
    { 
     return currCont; 
    } 

    private: 
    static size_t counter; 
}; 

// ...later... 

    x = start; 
    // 0...n go to end 
    for (; x; x = x->next) 
    { 
     if (l1 == x->length) 
     { 
      if (compare == x->word) 
      { 
       outfile << "Word: " << compare << " is the " << x->howMany() << " Word in the book.\n"; 
       count++; 
      } 
     } 
    } 
    outfile << "Word: " << compare << ", " << count << "x found!\n"; 
    count = 0; 
} 
+0

我试图应用您的更改,但在'int curcounter'这一行中。我收到错误信息:\t \t 32 9 main.cpp [错误]静态成员函数中成员'Word :: curcounter'的无效使用 – user3794592 2014-10-03 11:19:42

+0

'howMany'不应该是'静态' – 2014-10-03 11:21:51

+0

您对错误表示抱歉。我编辑我的代码。 – Logman 2014-10-03 13:20:52

1

变量counter是静态的,这意味着它是班上唯一的一个。

所以说我正在用三个字读:“a”,“b”和“c”。当我呼吁howMany“一”,它会返回3,“B”和“C”的howMany也将返回3.

我建议让您的所有Word S IN一个std::vector,只是呼吁std::vector.size()得到Word计数。我将从counterhowMany中删除static,并将字数作为参数传递给Word构造函数,以便您可以将其存储在您的counter成员变量中。

+0

+1,虽然我怀疑OP被告知要写一个链表类,所以虽然你的建议是一个更好的主意,但它不会被允许:)不需要在Word中存储一个计数,你可以通过减去矢量中第一个元素的地址,在矢量中找到它的位置。这样做的好处是,当你在矢量 – 2014-10-03 11:17:54

+0

@JonathanWakely的中间添加/删除元素时,你不需要更新每个元素的计数,这会更加理想。我只是想改造,而不是去大修,因为我不知道哪里会结束:) – 2014-10-03 11:34:54