题目
编写程序,从一段英文长文本中解析出所有单词(忽略标点与大小写归一化),利用 std::unordered_map<std::string, int> 在 O(N) 时间内高效统计每个词汇出现的频次;随后将键值对提取转移至 std::vector<std::pair<std::string, int>> 中,使用 std::sort 结合 Lambda 表达式按词频降序(词频相同时按字典序升序)输出 Top-K 热词榜单。
输入格式:无需外部输入(内置英文测试文本)。
输出格式:输出单词词频统计排行榜 Top 5。
数据范围与约定:字符串清洗、哈希聚合与二次排序。
思路与算法
1. 哈希表的极速聚合unordered_map[word]++ 能够在常数级均摊时间内直接完成“未见则插入初始化为 1,已见则累加”的逻辑,是词频统计的核心利器。
2. 无序哈希表无法直接排序unordered_map 本身是无序的,且不支持直接使用 std::sort(其迭代器非随机访问)。必须先将元素倾倒(Dump)到 vector 中才能进行灵活的多维度排序。
3. 标点过滤状态机
遍历字符时,连续的 std::isalpha 累加构词,一旦遇到分隔符且当前词非空,则完成一个词的提纯收尾。
完整程序
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cctype>
int main() {
std::string text = "C++ is fast, very fast! Modern C++ provides high-level abstractions, and C++ performance is unbeatable.";
std::unordered_map<std::string, int> freqMap;
std::string currentWord;
// 1. 字符清洗与分词聚合
for (char ch : text) {
if (std::isalnum(static_cast<unsigned char>(ch)) || ch == '+') {
currentWord += std::tolower(static_cast<unsigned char>(ch));
} else {
if (!currentWord.empty()) {
freqMap[currentWord]++;
currentWord.clear();
}
}
}
if (!currentWord.empty()) {
freqMap[currentWord]++;
}
// 2. 转储到 vector 进行排序
std::vector<std::pair<std::string, int>> wordList(freqMap.begin(), freqMap.end());
// 3. 排序策略:频次降序;若频次相同,按单词字典序升序
std::sort(wordList.begin(), wordList.end(), [](const auto& a, const auto& b) {
if (a.second != b.second) {
return a.second > b.second; // 频次高的排前面
}
return a.first < b.first; // 字典序小的排前面
});
std::cout << "--- 文本词频统计排行榜 Top 5 ---\n";
size_t topK = std::min(size_t(5), wordList.size());
for (size_t i = 0; i < topK; ++i) {
std::cout << "第 " << i + 1 << " 名: [\"" << wordList[i].first
<< "\"] 出现频次: " << wordList[i].second << " 次\n";
}
return 0;
}运行示例
输出:
--- 文本词频统计排行榜 Top 5 ---
第 1 名: ["c++"] 出现频次: 3 次
第 2 名: ["fast"] 出现频次: 2 次
第 3 名: ["is"] 出现频次: 2 次
第 4 名: ["abstractions"] 出现频次: 1 次
第 5 名: ["and"] 出现频次: 1 次