unordered_map 未正确更新
unordered_map not being updated properly
尝试使用以下代码片段将无序映射更新为只有小写字母,但它似乎在擦除一个键值对后停止 { [33 '!']: 3 } 并退出循环离开地图的其余部分未访问并打印部分更新的地图。
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
*/
似乎无法理解为什么它不会遍历完整的无序映射。
此外,不确定这是否有助于获得清晰的图片,但是,当使用标准地图而不是无序地图时,它会在需要更新地图的下一个字符的同一实例中给出地址边界错误,例如所以:
您不能在以这种方式迭代时擦除地图元素。当您擦除迭代器时,它会失效,因此您需要在删除元素之前明确地递增它。
试试这个代码:
for (auto it = m.begin(); it != m.end();)
if (!((*it).first >= 'a' && (*it).first <= 'z'))
it = m.erase(it);
else
++it;
C++ 的陷阱之一是大多数容器的迭代器在修改时失效。
std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::erase - cppreference.com
References and iterators to the erased elements are invalidated. Other iterators and references are not invalidated.
因此,当您从 m
移除项目时,当前迭代器将变得无效。
现在range base for loop uses iterators underneath.
我们使用 std::erase_if 算法修复它的野兽方法:
std::erase_if(m.begin(), m.end(), [](const auto& i) {
return !(std::islower(i.first));
});
尝试使用以下代码片段将无序映射更新为只有小写字母,但它似乎在擦除一个键值对后停止 { [33 '!']: 3 } 并退出循环离开地图的其余部分未访问并打印部分更新的地图。
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
*/
似乎无法理解为什么它不会遍历完整的无序映射。
此外,不确定这是否有助于获得清晰的图片,但是,当使用标准地图而不是无序地图时,它会在需要更新地图的下一个字符的同一实例中给出地址边界错误,例如所以:
您不能在以这种方式迭代时擦除地图元素。当您擦除迭代器时,它会失效,因此您需要在删除元素之前明确地递增它。
试试这个代码:
for (auto it = m.begin(); it != m.end();)
if (!((*it).first >= 'a' && (*it).first <= 'z'))
it = m.erase(it);
else
++it;
C++ 的陷阱之一是大多数容器的迭代器在修改时失效。
std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::erase - cppreference.com
References and iterators to the erased elements are invalidated. Other iterators and references are not invalidated.
因此,当您从 m
移除项目时,当前迭代器将变得无效。
现在range base for loop uses iterators underneath.
我们使用 std::erase_if 算法修复它的野兽方法:
std::erase_if(m.begin(), m.end(), [](const auto& i) {
return !(std::islower(i.first));
});