C++使用map统计vector元素出现次数的代码问题咨询
问题分析与解决
嘿,我来帮你拆解下这段代码为啥没达到预期效果~
你的核心问题出在对map::insert方法的理解上:当你尝试插入一个已经存在的key时,insert是不会修改原有值的,它会直接跳过这次插入操作。
咱们一步步看你的循环逻辑:
- 第一次遇到某个字符(比如
'b')时,m['b']因为key不存在,会自动在map里插入一个{'b', 0}的条目,然后m['b']+1得到1,这时候调用insert,因为key已经被m['b']触发插入了,insert操作实际不会生效?不对,其实第一次循环里,m[n]先触发了默认插入,之后的insert因为key已存在,直接失败,不过此时map里'b'的值是0?哦不对,等下,m[n]是读取操作吗?不,map的下标运算符[]是写操作——当key不存在时,它会插入一个默认值的元素,然后返回这个元素的引用。所以第一次m['b']的时候,map里已经有{'b', 0}了,然后m['b']+1是1,你再调用insert(pair<char, int>('b', 1)),这时候因为key已存在,insert完全不生效,所以map里'b'的值还是0?哦,原来我之前的分析还不够准确! - 第二次遇到
'b'时,m['b']返回已存在的0的引用,m['b']+1是1,再次调用insert,还是因为key存在不生效,map里'b'的值依然是0?这就更糟了,完全没统计上次数。
哦,原来你的代码不仅没增加计数,甚至第一次的默认插入值都没被更新,这才是问题的全貌——insert在key存在时的“无作为”,加上m[n]触发的默认插入,导致计数完全错误。
正确的解决方式
有两种简单的写法可以实现你的需求:
方式1:直接用map的下标自增(最简洁)
map的下标操作m[n]本身就有“不存在则插入默认值(int的默认值是0)”的特性,直接对它自增就能完美实现计数:
vector<char> v{ 'a', 'b', 'f', 'b', 'd', 'c', 'b', 'f', 's', 'v', 'x'}; map<char, int> m; for (char n : v) { m[n]++; // 不存在则插入0再+1,存在则直接+1 }
方式2:利用insert的返回值(适合想深入理解map操作的场景)
如果一定要用insert,可以通过它的返回值判断是否插入成功,然后手动更新已存在元素的计数:
vector<char> v{ 'a', 'b', 'f', 'b', 'd', 'c', 'b', 'f', 's', 'v', 'x'}; map<char, int> m; for (char n : v) { // insert返回一个pair:第一个是指向元素的迭代器,第二个是是否成功插入的bool值 auto insert_result = m.insert(std::make_pair(n, 1)); if (!insert_result.second) { // 说明key已存在,直接给对应计数加1 insert_result.first->second++; } }
如果你的编译器支持C++17,还可以用结构化绑定让代码更清爽:
for (char n : v) { auto [it, inserted] = m.insert({n, 1}); if (!inserted) { it->second++; } }
内容的提问来源于stack exchange,提问作者Chumicat
相关产品推荐
相关产品推荐

