C++中使用unordered_map统计相邻元素对出现次数的正确语法
问题原因
- 语法层面:C++标准库没有为
std::pair<int, int>提供默认哈希函数,无法直接作为std::unordered_map的键类型,因此你的两种写法都会触发编译错误。 - 逻辑层面:你的代码缺失了需求中要求的
arr[i] != arr[i-1]判断,会把相邻相等的元素对也计入统计;且初始赋值时arr[i]=temp的i未初始化,属于语法小错误。
正确实现方案
方案1:使用std::map替代std::unordered_map(最简单无额外代码)
std::map是有序关联容器,依赖operator<进行键的比较,而std::pair默认支持小于比较,无需额外定义即可直接作为键使用。
#include <iostream> #include <vector> #include <map> using namespace std; int main() { int n; cin >> n; // 动态输入数组长度 vector<int> arr(n); map<pair<int, int>, int> cnt_map; cin >> arr[0]; for (int i = 1; i < n; i++) { cin >> arr[i]; if (arr[i] != arr[i-1]) { // 仅统计符合要求的元素对 cnt_map[{arr[i-1], arr[i]}]++; } } // 输出统计结果 for (auto& entry : cnt_map) { cout << "(" << entry.first.first << ", " << entry.first.second << ") -> " << entry.second << endl; } return 0; }
方案2:保留std::unordered_map的实现
如果需要unordered_map的哈希表O(1)查找性能,可以选择以下两种方式之一:
方式A:自定义pair的哈希函数
#include <iostream> #include <vector> #include <unordered_map> using namespace std; // 自定义pair<int,int>的哈希函数 struct pair_hash { template <class T1, class T2> size_t operator () (const pair<T1,T2> &p) const { auto h1 = hash<T1>{}(p.first); auto h2 = hash<T2>{}(p.second); return h1 ^ (h2 << 1); // 简单哈希组合,可根据需求替换为更优实现 } }; int main() { int n; cin >> n; vector<int> arr(n); // 传入自定义哈希类型作为unordered_map第三个模板参数 unordered_map<pair<int, int>, int, pair_hash> cnt_map; cin >> arr[0]; for (int i = 1; i < n; i++) { cin >> arr[i]; if (arr[i] != arr[i-1]) { cnt_map[{arr[i-1], arr[i]}]++; } } for (auto& entry : cnt_map) { cout << "(" << entry.first.first << ", " << entry.first.second << ") -> " << entry.second << endl; } return 0; }
方式B:将pair编码为单个64位整数作为键
对于取值范围不超过int最大值的两个整数,可以将其组合为一个uint64_t类型作为键,无需自定义哈希:
#include <iostream> #include <vector> #include <unordered_map> using namespace std; int main() { int n; cin >> n; vector<int> arr(n); unordered_map<uint64_t, int> cnt_map; cin >> arr[0]; for (int i = 1; i < n; i++) { cin >> arr[i]; if (arr[i] != arr[i-1]) { // 编码规则:前32位存arr[i-1],后32位存arr[i] uint64_t key = (static_cast<uint64_t>(arr[i-1]) << 32) | static_cast<uint32_t>(arr[i]); cnt_map[key]++; } } // 输出时解码即可 for (auto& entry : cnt_map) { int first = static_cast<int>(entry.first >> 32); int second = static_cast<int>(entry.first & 0xFFFFFFFF); cout << "(" << first << ", " << second << ") -> " << entry.second << endl; } return 0; }
以上三种实现都可以得到你给出的示例统计结果。
内容的提问来源于stack exchange,提问作者Kirti Purohit
相关产品推荐
相关产品推荐

