2014-10-01 42 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; 
} 

但是,性病::名單是數據結構的一個錯誤的選擇在這裏,應該給運行時間帶來不好的複雜性。