计算列表元素

时间:2014-10-03 10:40:20

标签: c++ linked-list counter

我正在编写一个双向链表,在其中我从给定文件中读取字符串。 因此,我编写了一个名为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";
}

4 个答案:

答案 0 :(得分:2)

  

我现在的问题是我的计数器只计算整个节点的数量。

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

  

所以我只看到创建了大约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;

答案 1 :(得分:1)

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

所以说我读3个字:“a”,“b”和“c”。当我在“a”上拨打howMany时,它将返回3,“b”和“c”的howMany也将返回3.

我建议您将所有Word保留在std::vector中,然后只需致电std::vector.size()即可获得Word次。我会从staticcounter中移除howMany,并将单词count in作为参数传递给Word构造函数,以便将其存储在{{1}中成员变量。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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;
}