计算列表元素

问题描述 投票:0回答:4

我正在编写一个双向链表,其中我从给定文件中读取字符串。

因此,我编写了一个名为 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 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";
}
c++ linked-list counter
4个回答
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
投票
counter

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


假设我正在阅读 3 个单词:“a”、“b”和“c”。当我在“a”上调用

howMany

时,它将返回 3,“b”和“c”的

howMany
也会返回 3。

我建议将所有

Word

放在

std::vector
中,然后致电
std::vector.size()
来获取
Word
计数。我将从
static
counter
中删除
howMany
并将字数计数作为参数传递给
Word
构造函数,以便您可以将其存储在
counter
成员变量中。
    


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

© www.soinside.com 2019 - 2024. All rights reserved.