2014-10-01 41 views
-1

对于我的项目,我需要读入一个文件并计算每个字符出现的时间并将其存储在链接列表中。下面是我在程序的文件部分阅读:C++字符频率链接列表

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()有关,因为它删除了最后一个元素,但我不知道要避免这个问题。

在此先感谢您的帮助!

+1

一个'的std ::地图'比用链表这样做更容易了一大堆。 – PaulMcKenzie 2014-10-01 02:57:59

+1

您是否需要使用列表?映射类型更直观,可能会变得更好。 – 2014-10-01 02:59:05

+0

'std :: map CharMap; ... while(!inFile){inFile >> ch; CHARMAP [CH] ++;如果你使用地图,那么这就是你的两个问题的解决方案。一个可怜的2线循环。 – PaulMcKenzie 2014-10-01 03:02:22

回答

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 
    } 
    //... 
+0

非常感谢!我得到它的工作!我已经创建了charFrequency类,只是没有发布它的代码,但添加结构和while循环让它工作。我还采取了你的建议初始化1的计数,而不是0.再次感谢! – 2014-10-01 17:56:44

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

但是,性病::名单是数据结构的一个错误的选择在这里,应该给运行时间带来不好的复杂性。