如何从C++的vector或数组中选取出现频率最高的前5个数字?
实现std::vector的Top5频率数字提取
没问题,我来帮你搞定这个需求!要从std::vector<int>里找出出现频率最高的Top5数字并存入新vector,我们可以分步骤实现,完全匹配你给出的示例结果。
完整解决方案代码
#include <vector> #include <unordered_map> #include <algorithm> #include <iostream> #include <utility> // 用于std::make_pair std::vector<int> getTopFrequencyNumbers(const std::vector<int>& numbers) { // 1. 统计每个数字的出现频率,以及首次出现的位置 std::unordered_map<int, int> frequency_map; std::unordered_map<int, size_t> first_occurrence_map; for (size_t idx = 0; idx < numbers.size(); ++idx) { int num = numbers[idx]; if (frequency_map.find(num) == frequency_map.end()) { frequency_map[num] = 1; first_occurrence_map[num] = idx; } else { frequency_map[num]++; } } // 2. 将统计结果转换为可排序的结构:存储(数字, (频率, 首次出现位置)) std::vector<std::pair<int, std::pair<int, size_t>>> sorted_elements; for (const auto& entry : frequency_map) { sorted_elements.emplace_back(entry.first, std::make_pair(entry.second, first_occurrence_map[entry.first])); } // 3. 自定义排序规则:先按频率降序,频率相同则按首次出现位置升序(先出现的排前面) std::sort(sorted_elements.begin(), sorted_elements.end(), [](const auto& a, const auto& b) { if (a.second.first != b.second.first) { return a.second.first > b.second.first; } // 频率相同时,按首次出现的先后排序,和你的示例逻辑一致 return a.second.second < b.second.second; }); // 4. 生成Top5结果并存入新vector,同时输出TOP列表 std::vector<int> top5_result; size_t take_count = std::min(sorted_elements.size(), static_cast<size_t>(5)); for (size_t i = 0; i < take_count; ++i) { top5_result.push_back(sorted_elements[i].first); std::cout << "TOP " << (i + 1) << ": " << sorted_elements[i].first << std::endl; } return top5_result; } // 测试示例 int main() { std::vector<int> numbers = {32, 32, 32, 12, 12, 11, 11, 11, 9}; std::vector<int> top5 = getTopFrequencyNumbers(numbers); // 可以验证结果vector的内容 std::cout << "\nResult vector content: "; for (int num : top5) { std::cout << num << " "; } std::cout << std::endl; return 0; }
代码解释
- 统计频率与首次出现位置:用两个
std::unordered_map分别记录每个数字的出现次数,以及它第一次在原vector中出现的索引。这一步是为了处理频率相同的情况——比如你的示例中32和11都出现3次,我们可以通过首次出现位置保证先出现的数字排在前面。 - 转换为可排序结构:把哈希表中的键值对转换成vector,方便后续自定义排序。
- 自定义排序逻辑:核心规则是频率高的优先,如果频率相同,则首次出现早的优先,这完全匹配你给出的示例输出(TOP1:32,TOP2:11)。如果你需要按数值大小排序(比如频率相同的数字按从大到小排),只需要把排序lambda里的第二部分改成
return a.first > b.first;即可。 - 生成结果:取排序后的前5个元素(如果不同数字的总数不足5,就取全部),存入目标vector,同时输出你需要的TOP列表。
边界情况处理
- 如果原vector为空,函数会返回空的结果vector。
- 如果原vector中只有3种不同数字,结果vector就会包含这3个数字的Top3列表。
- 如果所有数字都相同,结果vector只会包含这个数字。
内容的提问来源于stack exchange,提问作者theshepherd
相关产品推荐
相关产品推荐

