簡體   English   中英

計算每個單詞在其輸入C ++中出現的次數

[英]Count how many times each distinct word appears in its input C++

#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。 可能是什么問題呢? 我不確定迭代器不為空的測試是否正確。

由於map使用默認的構造函數自動構造一個項目,因此當您訪問尚不存在的鍵時,您可以簡單地說:

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

新項目的默認值為0(請參閱此問題 )。

您以前的映射邏輯很好,只不過您的條件已逆轉; 它應該是if (it == m.end())不是的!= ,因為find()返回end()時, 找到的元素。 正如GWW在他的答案中指出的那樣,當項目已經在地圖上時, insert無效,這是您唯一使用它的時間。

另外,您的循環沒有正確處理輸入; 您需要讀入值之后但使用它之前檢查流的狀態是否無效(因為如果該流在其末尾,則該值是垃圾)。 處理輸入的慣用方式是使用while (is >> value)構造; 如果您想自己做,那么這是等效的:

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

   // Process words...
}

最后,當您的變量“ words”一次只包含一個單詞時,會有點誤導;-)

我將從cplusplus.com引用。

因為映射容器不允許重復的鍵值,所以插入操作將檢查插入的每個元素是否在容器中已經存在具有相同鍵值的另一個元素,如果存在,則不插入該元素,並且在任何情況下其映射值都不會更改方式。

在您的代碼中,您嘗試插入地圖中已有的元素之上。 你應該改變

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

it->second+=1;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM