计数列表元素



我正在编程一个双链表,从给定的文件中读取字符串。因此,我写了一个名为Node的类,在其中我存储了一个字符串(读取的单词)和一些用于单词长度和其他参数的整数。

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

现在我想向用户显示找到的单词在文本中的哪个位置,例如:

"在文本文件的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 openn";
    // 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";
}

我现在的问题是,我的计数器只是计算总共创建了多少节点。

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

所以我只看到创建了大约56000个节点,但我无法存储节点的数量。

如果您希望每个节点都有一个不同的数字,那么您不能将一个数字存储在一个地方,并期望它有几个不同的值!

你需要

  • 或者在每个节点中存储一个数字作为成员变量,不是静态变量(但如果节点是从列表的开头或中间添加或删除的,请确保它们都是正确的,如果程序中同时有两个列表,请确保列表中的第一个节点的数字为0,即它必须是该列表中的数字,而不仅仅是已分配节点的全局计数器。)

  • 更简单,只需在遍历列表时保留一个计数器,并为您看到的每个节点递增。你已经在统计匹配单词的数量了,为什么不能只统计所有检查单词的总数,包括不匹配的单词?

例如:

while (file >> compare)
{
    int checked = 0;
    int found = 0;
    for (Word* x = start; x; x = x->next)
    {
        if (compare == x->word)
        {
            outfile << "Word: " << compare << " found in book Nr.: " << x->book << ", chapter: " << x->chapter << " at word " << checked << "!n";
            found++;
        }
        checked++;
    }
    outfile << "Word: " << compare  << ", " << found << "x found!n";
}

请注意,我在循环中声明变量(而不是在函数的顶部),并且不必检查单词长度,因为比较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;

变量counter是静态的,这意味着它是类中唯一的变量。

假设我在读三个单词:"a"、"b"one_answers"c"。当我在"a"上调用howMany时,它将返回3,"b"one_answers"c"的howMany也将返回3。

我建议将所有的Word保存在std::vector中,只需调用std::vector.size()即可获得Word计数。I将从counterhowMany中删除static,并将单词计数作为参数传递给Word构造函数,这样您就可以将其存储在counter成员变量中。

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

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

快速修复:

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;
}

相关内容

  • 没有找到相关文章

最新更新