为何无法向STL map插入值?map值始终为0问题排查
STL map插入键值对后值始终为0?问题出在这!
我一眼就看出你代码里的问题啦——核心问题出在**map<int, int>的operator[]行为**上,咱们一步步拆解:
为什么原来的代码会失效?
当你写if(num[a])的时候,map的operator[]有个“隐藏特性”:如果键a不存在,它会自动插入一个键为a、值为**默认构造值(int类型就是0)**的元素。这就导致:
- 第一次处理某个
a时,num[a]先悄悄创建了(a, 0)的项,此时if(num[a])判断为假,进入else分支 - 但
else里的num.insert(make_pair(a,1))会因为键a已经存在(刚才operator[]刚插的),所以insert操作完全不会生效,值还是0 - 后续再遇到同一个
a时,num[a]的值还是0,if条件依然不成立,还是走无效的insert,结果所有值都停在0
修复方案(两种可选)
方案1:用find检查键是否存在(最直观的修正)
避免直接用operator[]触发自动插入,改用find明确判断键是否存在:
#include<iostream> #include<map> using namespace std; int main() { int n; cin>>n; int a; map<int, int> num; map<int, int>::iterator p; for (int i = 0;i < n; i++){ cin>>a; auto it = num.find(a); // 查找键a是否存在 if(it != num.end()) { it->second++; // 存在则计数+1 } else { num.insert(make_pair(a,1)); // 不存在则插入初始值1 } } for (p=num.begin();p!=num.end(); p++) cout<<p->first<<" "<<p->second<<endl; return 0; }
方案2:直接利用operator[]的特性简化代码(更简洁)
既然operator[]会自动创建值为0的元素,那咱们直接num[a]++就行——不存在的话,先创建0然后++变成1;存在的话直接+1,完美符合计数需求:
#include<iostream> #include<map> using namespace std; int main() { int n; cin>>n; int a; map<int, int> num; map<int, int>::iterator p; for (int i = 0;i < n; i++){ cin>>a; num[a]++; // 一行搞定计数,无需额外判断 } for (p=num.begin();p!=num.end(); p++) cout<<p->first<<" "<<p->second<<endl; return 0; }
测试验证
输入6 10 1 10 20 30 20(先输入n=6,再输入6个数字:10、1、10、20、30、20),两种方案都会输出预期的结果:
1 1 10 2 20 2 30 1
内容的提问来源于stack exchange,提问作者fine
相关产品推荐
相关产品推荐

