如何在任意文本序列中统计每个单词的出现次数.
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <algorithm> // For replace_if() & for_each()
#include <map>
#include <cctype> // For isalpha()
using std::string;
using namespace std;// istream_iterator
#include <iterator>
int main()
{
std::cout << "Enter some text and enter * to end:\n";
string text_in {};
//从标准输入流读取到 text_in 中的文本是通过函数 getline() 得到的字符串
std::getline(std::cin, text_in, '*');
// replace_if() 算法用空格替换了输入中的所有非字母字符
std::replace_if(std::begin(text_in), std::end(text_in),
[](const char& ch){ return !isalpha(ch); }, ' ');
istringstream text(text_in); // 用 text_in 生成一个 istringstream 对象 text
istream_iterator<string> _begin(text); // Stream iterator
istream_iterator<string> _end; // End stream iterator
std::map<string, size_t> words; // Map to store words & word counts
size_t max_len {}; // Maximum word length
// for_each() 会将第 3 个参数指定的函数对象运用到前两个参数所指定范围内的元素上
//因而调用 for_each() 会将输入的所有单词都插入到这个 map 容器中,并且累加计算出每个单词
//的出现次数,计算出最大单词的长度,一条语句就实现了上面这些功能。
std::for_each(_begin, _end, [&max_len, &words](const string& word)
{ words[word]++;
max_len = std::max(max_len, word.length());
});
// lambda 通过将每个单词作为下标来将它们以键的方式保存在容器中,并增加单词关联的值。如果单词不在容器中,
// 会以这个单词为键(值为 1)来生成一个新的元素。如果单词先前就被添加到容器中,就自动增加值。
size_t per_line {4}, count {};
for(const auto& w : words)
{
std::cout << std::left << std::setw(max_len + 1) << w.first << std::setw(3)
<< std::right << w.second << " ";
if(++count % per_line == 0)
std::cout << std::endl;
}
std::cout << std::endl;
}