【问题标题】:C++ Character Frequency Linked ListC++ 字符频率链表
【发布时间】:2014-10-01 02:55:25
【问题描述】:

对于我的项目,我需要读入一个文件并计算每个字符出现的次数并将其存储在一个链表中。以下是我在程序文件部分的阅读内容:

ifstream inFile;
ofstream outFile;

inFile.open(inputfile.txt);

char ch;

list<charFrequency> charFreqList;
list<charFrequency>::iterator i;

inFile >> ch;
while (!inFile.eof())
{
    charFrequency cf(ch);
    charFreqList.push_back(cf);

    for (i = charFreqList.begin(); i != charFreqList.end(); ++i)
    {
        if (i->getCharacter() == cf.getCharacter())
        {
            i->increment();
            charFreqList.pop_back();
        }
    }

    inFile >> ch;
}

inFile.close();

我需要程序通过,如果字符已经在链表中,它只需要增加字符的计数,但只在列表中留下一个字符实例,但是,我收到一条错误消息说明“列表迭代器不可实现”。我知道它与 pop_back() 因为它删除了最后一个元素有关,但我不知道如何避免这个问题。

提前感谢您的帮助!

【问题讨论】:

  • std::map&lt;char, int&gt; 比使用链表更容易。
  • 您需要使用列表吗?映射类型更直观,并且可能会更好地执行。
  • std::map&lt;char,int&gt; CharMap;...while(!inFile) { inFile &gt;&gt; ch; CharMap[ch]++; } 如果您使用地图,这实质上就是解决这两个问题的方法。一个可怜的 2 行循环。
  • 是的,很遗憾我必须使用链表。
  • @FreddyRivas - 你应该如何同时存储一个字符一个计数?这样做的唯一方法是将结构存储在包含字符和计数器的链表中,类似于std::list&lt;std::pair&lt;char, int&gt;&gt;。你可以使用这个吗?如果没有,请准确列出您可以使用的内容,因为我认为它不会以任何其他方式工作。

标签: c++ list linked-list


【解决方案1】:

首先,如果字符不存在,则仅添加charFrequency,否则增加计数。如果一个新的charFrequency 以 1 开头,也会更容易。

其次,将输入循环更改为不检查 eof()。这在 SO 上的许多线程中都有解释。

class charFrequency
{
   int count;
   char ch;
   public:
       void increment() { ++count; }
       char getCharacter() const { return ch; }
       int getCount() const { return count; }
       charFrequency(char c) : ch(c), count(1) {}
};

最后,让我们使用一些 C++ 并使用 std::find_if() 算法函数而不是编写循环。下面介绍一个查找字符的函数对象。

struct FindCharacter
{
    char ch;
    FindCharacter(char c) : ch(c) {}
    bool operator()(charFrequency& cf) const
    { return cf.getCharacter() == ch;   }
};

所以现在把所有这些放在一起,我们有这个:

#include <list>
#include <algorithm>
#include <fstream>

    //...
    while (ifs)
    {
        ifs >> ch;

        // Search for character 
        std::list<charFrequency>::iterator it = std::find_if(charFreqList.begin(), charFreqList.end(), FindCharacter(ch));

        // if not found, add new charFrequency to list
        if ( it == charFreqList.end())
            charFreqList.push_back(charFrequency(ch));
        else
            it->increment();  // increment
    }
    //...

【讨论】:

  • 非常感谢!!我让它工作了!我已经创建了 charFrequency 类,只是没有发布它的代码,但是添加了结构和 while 循环让它工作。我还听取了您关于将计数初始化为 1 而不是 0 的建议。再次感谢!!
【解决方案2】:

您无需将其推入列表并将其删除。您可以执行以下操作,或者从代码中的 if 条件中断,然后删除最后一个元素(不在循环中)

list<charFrequency> charFreqList;
list<charFrequency>::iterator i;
while (!inFile.eof())
{
    charFrequency cf(ch);
    Predicate pre(ch); //Write your predicate functor

    //check if the char is present
    i = std::find_if(charFreqList.begin(), charFreqList.end(), pred); 
    if( i != charFreqList.end() )
      i->increment();
    else
      charFreqList.push_back(ch); //insert only when not present

    inFile >> ch;
}

然而,std::list 在这里是一个错误的数据结构选择,它会带来不好的运行时间复杂度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-19
    • 2011-10-23
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多