在下面的 C++ 代码中,unordered_map 元素意外消失的行为让我很困惑。在第一个for循环中,我将每个元素的剩余部分存储在timemoduled by 60 中,并将其计数存储在 中unordered_map<int, int> m,在第二个 for循环中,我将内容打印在 中m,到目前为止,一切似乎都正常。
cout如下
0:1
39:1
23:1
18:1
44:1
59:1
12:1
38:1
56:2
17:1
37:1
24:1
58:1
Run Code Online (Sandbox Code Playgroud)
然而在第三个for循环中,它只打印了 中的部分元素m,
0:1
39:1
58:1
0:1
Run Code Online (Sandbox Code Playgroud)
看来很多元素都m被n += m[remainder]*m[60-remainder];操作删除了。我对这种行为感到很困惑,你能理解这是怎么回事吗?实在是太迷茫了。
#include <iostream>
#include<unordered_map>
#include<vector>
using namespace std;
int main() {
vector<int> time ({418,204,77,278,239,457,284,263,372,279,476,416,360,18});
int n =0;
unordered_map<int,int> m; // <remiander,cnt>
for (auto t:time)
m[t%60]++;
for (auto [remainder,cnt]:m)
cout<<remainder<<":"<<cnt<<endl;
cout<<endl;
for (auto [remainder,cnt]:m){
cout<<remainder<<":"<<cnt<<endl;
if (remainder==0 || remainder==30)
n += cnt*(cnt-1)/2;
else
n += m[remainder]*m[60-remainder];
}
}
Run Code Online (Sandbox Code Playgroud)
第三个循环[]在循环内使用运算符。
for (auto [remainder,cnt]:m){
// ...
n += m[remainder]*m[60-remainder];
Run Code Online (Sandbox Code Playgroud)
unordered_map[]如果导致重新散列,则会使所有现有迭代器无效。这包括范围迭代期间使用的隐式迭代器。
如图所示,m[remainder]无法导致重新散列,因为它只能访问无序映射中的现有值,但对于 来说则不然m[60-remainder],从而导致未定义的行为。
您只需要删除[]运算符的这种用法并将其替换为等效的find()(当然,end()如果返回值,则正确处理该值)。