尝试使用以下代码片段更新无序Map,使其仅包含小写字母,但似乎在擦除一个键值对{ [33 '!']后停止:3 },并退出循环,留下Map的其余部分未被访问,并打印部分更新的Map。
for (auto &i : m)
if (!(i.first >= 'a' && i.first <= 'z'))
m.erase(i.first);
以下调试图像显示了上述内容
完整代码如下:
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main()
{
string line = "Try! Try! Try! until you succeed";
//getline(cin, line);
unordered_map<char, int> m;
for (int i = 0; line[i]; i++)
{
char lower = (char)tolower(line[i]);
if (m.find(lower) == m.end())
m.insert(make_pair(lower, 1));
else
m[lower]++;
}
for (auto &i : m) //only updates until !
if (!(i.first >= 'a' && i.first <= 'z'))
m.erase(i.first);
cout<<"The freq. map so formed is : \n";
for (auto &i : m)
cout<<i.first<<"\t"<<i.second<<endl;
return 0;
}
/*
OUTPUT :
The freq. map so formed is :
d 1
t 4
r 3
e 2
y 4
l 1
o 1
5
n 1
u 3
i 1
s 1
c 2
*/
我不明白为什么它不能遍历整个无序Map。
此外,不确定这是否有助于清晰的图像,但是,当使用标准Map而不是无序Map时,它会在同一示例中给出地址边界错误,其中Map的下一个字符需要像这样更新:
2条答案
按热度按时间eqqqjvef1#
C++的一个陷阱是迭代器在被修改时对大多数容器无效。
std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::erase - cppreference.com
对被擦除元素的引用和迭代器无效,其他迭代器和引用不会无效。
所以当你从
m
中删除项时,当前迭代器就变得无效了。现在range base for loop uses iterators underneath。
最好的解决方法是使用std::erase_if算法:
2lpgd9682#
在这种方式迭代时,你不能擦除map的元素。当你擦除迭代器时,它将变得无效,所以你需要在删除元素之前显式地递增它。
请尝试以下代码: