如何在C++中输出容器内频率最高的前10个单词
解决:输出频率最高的前10个单词
嘿,我看你现在的问题是没法正确输出频率最高的前10个单词,反而输出了按插入顺序来的前10个重复单词对吧?我帮你拆解下代码里的问题,然后给出修改方案。
当前代码的问题分析
count变量未初始化:你在for循环里用了count但没给初始值,这会导致未定义行为——程序可能随机输出内容,甚至直接崩溃。- 循环条件错误:原来的for循环条件
count<=10, ++rit , ++count写法逻辑混乱,逗号表达式只会判断第一个count<=10,但因为count没初始化,这个条件完全不可靠,而且也没判断迭代器是否到末尾,容易出现越界问题。 - 虽然你用了
multimap的反向迭代器试图从高频率到低频率遍历,但前面的问题导致实际输出的不是你想要的前10个最高频单词。
修改后的代码(保留multimap写法)
// Displays 10 most frequent words in KnownWords void WordStats::DisplayMostFreqKnownWords(){ int count = 0; // 必须初始化count,避免未定义行为 multimap<int, string> displayFreqWords; // 遍历KnownWords,把单词和对应的频率插入multimap for (auto Paragraph = KnownWords.begin(); Paragraph != KnownWords.end(); ++Paragraph) { string word = Paragraph->first; int cnt = Paragraph->second.size(); displayFreqWords.insert(make_pair(cnt, word)); // 用make_pair简化写法 } cout << " Word Count\n"; // 反向迭代器从最高频率开始遍历,同时限制最多取10个,且迭代器不能到末尾 for (auto rit = displayFreqWords.rbegin(); rit != displayFreqWords.rend() && count < 10; ++rit, ++count) { string word = rit->second; int cnt = rit->first; cout << setw(15) << word << setw(10) << cnt << endl; } }
关键修改点说明
- 给
count初始化了0,这是解决问题的核心之一,未初始化变量是C++里常见的坑。 - 调整了for循环的条件:同时判断迭代器是否有效(
rit != displayFreqWords.rend())和count < 10,这样既不会在单词总数不足10个时越界,又能保证只取前10个最高频的单词。 - 用
auto代替了冗长的迭代器类型(C++11及以上支持,如果你用旧标准,改回multimap<int,string>::reverse_iterator即可),代码更简洁。
更灵活的替代方案(用vector排序)
如果你想自定义排序规则(比如频率相同时按单词字典序排列),可以用vector存储频率和单词,再手动排序,这种写法有时候效率更高:
void WordStats::DisplayMostFreqKnownWords(){ vector<pair<int, string>> wordFreqList; // 把KnownWords里的单词和频率转存到vector for (auto& entry : KnownWords) { wordFreqList.emplace_back(entry.second.size(), entry.first); } // 按频率降序排序;如果频率相同,按单词字典序升序排序(可选) sort(wordFreqList.begin(), wordFreqList.end(), [](const pair<int, string>& a, const pair<int, string>& b) { if (a.first != b.first) { return a.first > b.first; // 频率高的在前 } return a.second < b.second; // 频率相同则单词字典序在前 }); cout << " Word Count\n"; int count = 0; for (auto& entry : wordFreqList) { if (count >= 10) break; cout << setw(15) << entry.second << setw(10) << entry.first << endl; ++count; } }
这样修改后,就能输出你期望的频率最高的前10个单词啦!
内容的提问来源于stack exchange,提问作者muzzi
相关产品推荐
相关产品推荐

