C ++字符频率链接列表

时间:2014-10-01 02:55:25

标签: c++ list linked-list

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

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();

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

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您不需要进入列表并将其删除。您可以执行类似下面的操作,或者从代码中的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在这里是一个错误的数据结构选择,它会给运行时间带来很大的复杂性。

答案 1 :(得分:0)

首先,如果角色不存在,则只添加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
    }
    //...