C++使用map求解孤独整数时双位数输入返回空值问题咨询
问题说明
给定一个整数数组,除一个元素仅出现一次外,其余所有元素均出现两次,要求找出该唯一元素。
- 示例:当数组
a = {1,2,3,4,3,2,1}时,唯一元素为4。
已知XOR异或运算是该问题的最优求解方案,但尝试用map实现逻辑时出现异常:当输入包含双位数元素时,最终返回结果默认为null。
原实现代码如下:
using namespace std; int main(){ vector<int> a = {34, 95, 34, 64, 45, 95, 16, 80, 80, 75, 3, 25, 75, 25, 31, 3, 64, 16, 31}; //vector<int> a = {1, 2, 3, 4, 5, 1, 2, 3, 4}; int lone_int = 0; map<int, int> int_freq; for(int i = 0;i<a.size();i++){ int key = a[i]; int_freq[key] = int_freq[key] + 1; } for(const auto &x: int_freq){ if(x.second == 1)lone_int = x.first; else lone_int = '/0'; cout << x.first << " " << x.second << endl; } cout << lone_int << endl; }
错误原因
这个bug和元素是不是双位数没有任何关系,核心问题出在遍历频率表的循环逻辑:
map是有序容器,会按照key的大小升序遍历元素。你在遍历每个键值对时,只要当前元素出现次数不是1,就会把lone_int重新赋值为'/0'——这意味着哪怕你之前已经遍历到了出现1次的目标元素、把值存到了lone_int里,后续遍历到任何一个出现两次的元素,都会把之前存的正确值覆盖掉。- 你注释里的个位数测试用例刚好能跑对,是因为那个用例里唯一出现一次的元素
5是key最大的元素,排在遍历顺序的最后一位,遍历到它之后没有后续元素覆盖值,才让你误以为个位数场景逻辑正常。而你写的双位数测试用例里,唯一元素是45,后面还有64、75、80、95这些出现两次的元素,遍历到这些元素时就会把lone_int覆盖,最终输出错误结果。 - 额外提一句,你写的
'/0'是多字符字面量,并不是C++里的空字符'\0',本身写法也是错的。
修复方法
删掉循环里的else分支即可,找到频率为1的元素后可以直接跳出循环,不需要再遍历后续内容,也避免值被覆盖:
for(const auto &x: int_freq){ cout << x.first << " " << x.second << endl; if(x.second == 1){ lone_int = x.first; break; // 找到目标直接终止循环,避免后续误修改 } }
修复后运行代码,就能正确得到唯一元素45。
内容的提问来源于stack exchange,提问作者tommyboy
相关产品推荐
相关产品推荐

