2011-03-19 52 views
0
#include <iostream> 
#include <string> 
#include <sstream> 
#include <map> 

int main() 
{ 
    std::string input; 
    std::cout << "Enter input: "; 
    std::getline(std::cin, input); 

    std::map<std::string, int> m; 
    std::map<std::string, int>::iterator it; 
    std::istringstream iss(input); 
    std::string words; 

    do { 
     iss >> words; 
     it = m.find(words); 
     if(it != m.end()) 
     { 
      m.insert(it, std::pair<std::string, int>(words, m[words] + 1)); 
     } 
     else 
     { 
      m.insert(std::pair<std::string, int>(words, 1)); 
     } 
    }while(iss); 

    for(std::map<std::string, int>::iterator it = m.begin(); it != m.end(); ++it) 
    { 
     std::cout << it->first << " - " << it->second << std::endl; 
    } 
    return 0; 
} 

問題是,即使出現兩次,它也會爲每個單詞打印1個字。可能是什麼問題呢?我不確定我的迭代器測試是否爲空是正確的。計算每個不同單詞出現在其輸入中的次數C++

+0

http://stackoverflow.com/questions/4888879/elegant-ways-to-count-the-frequency-of-words-in-a-file – 2011-03-19 18:17:24

+0

您還可以在這裏看到其他解決方案:[優雅的方法來計算文件中的單詞頻率](http://stackoverflow.com/questions/4888879/elegant-ways-to-count-the-frequency-of-文字中的文字) – Nawaz 2011-03-19 18:33:38

回答

2

因爲map默認構造自動構建一個項目,當您訪問的關鍵不存在,你可以簡單地說:

while (iss >> words) { 
    ++m[words]; 
} 

的新項目的默認值是0(見this question)。

你以前的地圖邏輯很好,除了你有條件反轉;它應該是if (it == m.end())而不是!=,因爲find()返回end()當元素是而不是找到。正如GWW在他的回答中指出的那樣,insert在物品已經在地圖中時不起作用,這是您唯一使用它的時間。

此外,你的循環沒有正確處理輸入;您需要檢查數據流的狀態是否爲讀取的值,但是使用之前的(因爲如果數據流處於其末尾,則該值爲垃圾)。處理輸入的慣用方式是while (is >> value)結構;如果你想自己做,那麼這是等價的:

while (true) { 
    iss >> words; 
    if (!iss) { 
     break; 
    } 

    // Process words... 
} 

最後,這是一個有點誤導來命名變量「的話」時,將只包含在一個時間;-)

+0

不錯,很容易,謝謝 – Kobe 2011-03-19 17:29:50

1

我一個字將引用cplusplus.com

由於地圖容器不允許 重複的關鍵值,插入另一個 元件是否在具有相同鍵值的 容器中已存在的每個 元件 插入操作檢查,如果 所以,元件沒有插入,並且其映射值沒有以任何 的方式改變。

在你的代碼中,你試圖插入已經在地圖上的元素的頂部。你應該改變

m.insert(it, std::pair<std::string, int>(words, m[words] + 1)); 

it->second+=1; 
相關問題