C++更新unordered_map中的值,其中键值对的数据类型为int-unordered_set
C++ Updating values in a unordered_map, where the data type of key-value pair is int-unordered_set
我在解决 DSA 问题时观察到 C++ 标准模板库中的一个稍微奇怪的行为:
vector<int> v = {1, 7, 8, 3, 12};
unordered_map<int, unordered_set<int>> ump;
for (int i=0; i<v.size(); i++) {
unordered_set<int> us;
us.insert(56);
ump.insert(mp(v[i], us));
}
for (int i=0; i<v.size(); i++) {
unordered_set<int> us = ump.find(v[i])->second;
us.insert(67);
}
for (auto it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": ";
for (auto ait = it->second.begin(); ait!=it->second.end(); ait++) {
cout << *ait << ' ';
}
cout << '\n';
}
这里的输出是:
12: 56
3: 56
8: 56
7: 56
1: 56
但预期的输出应该是:
12: 67 56
3: 67 56
8: 67 56
7: 67 56
1: 67 56
而且我猜问题出在将值插入集合的过程中。而且我还认为,问题在某种程度上与“通过参考改变价值观”有关。但不确定是什么原因造成的。我做了更多实验,发现下面的代码片段有效。但是还是不确定,上面的代码哪里出了问题?
在下面的代码片段中,我没有通过引用直接更新集合,而是复制了它。然后插入我的值并再次将其复制到地图中,它起作用了。
vector<int> v = {1, 7, 8, 3, 12};
unordered_map<int, unordered_set<int>> ump;
for (int i=0; i<v.size(); i++) {
unordered_set<int> us;
us.insert(56);
ump.insert(mp(v[i], us));
}
for (int i=0; i<v.size(); i++) {
unordered_set<int> us = ump.find(v[i])->second;
unordered_set<int> us1;
for (auto it = us.begin(); it!=us.end(); it++) {
us1.insert(*it);
}
us1.insert(67);
ump.find(v[i])->second = us1;
}
for (auto it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": ";
for (auto ait = it->second.begin(); ait!=it->second.end(); ait++) {
cout << *ait << ' ';
}
cout << '\n';
}
这里的输出与预期的完全相同:
12: 67 56
3: 67 56
8: 67 56
7: 67 56
1: 67 56
unordered_set<int> us = ump.find(v[i])->second;
制作集合的副本,这样您的修改就不会更改 ump
中的值。您需要改用引用:
unordered_set<int>& us = ump.find(v[i])->second;
或使用auto
:
auto& us = ump.find(v[i])->second;
我在解决 DSA 问题时观察到 C++ 标准模板库中的一个稍微奇怪的行为:
vector<int> v = {1, 7, 8, 3, 12};
unordered_map<int, unordered_set<int>> ump;
for (int i=0; i<v.size(); i++) {
unordered_set<int> us;
us.insert(56);
ump.insert(mp(v[i], us));
}
for (int i=0; i<v.size(); i++) {
unordered_set<int> us = ump.find(v[i])->second;
us.insert(67);
}
for (auto it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": ";
for (auto ait = it->second.begin(); ait!=it->second.end(); ait++) {
cout << *ait << ' ';
}
cout << '\n';
}
这里的输出是:
12: 56
3: 56
8: 56
7: 56
1: 56
但预期的输出应该是:
12: 67 56
3: 67 56
8: 67 56
7: 67 56
1: 67 56
而且我猜问题出在将值插入集合的过程中。而且我还认为,问题在某种程度上与“通过参考改变价值观”有关。但不确定是什么原因造成的。我做了更多实验,发现下面的代码片段有效。但是还是不确定,上面的代码哪里出了问题?
在下面的代码片段中,我没有通过引用直接更新集合,而是复制了它。然后插入我的值并再次将其复制到地图中,它起作用了。
vector<int> v = {1, 7, 8, 3, 12};
unordered_map<int, unordered_set<int>> ump;
for (int i=0; i<v.size(); i++) {
unordered_set<int> us;
us.insert(56);
ump.insert(mp(v[i], us));
}
for (int i=0; i<v.size(); i++) {
unordered_set<int> us = ump.find(v[i])->second;
unordered_set<int> us1;
for (auto it = us.begin(); it!=us.end(); it++) {
us1.insert(*it);
}
us1.insert(67);
ump.find(v[i])->second = us1;
}
for (auto it = ump.begin(); it != ump.end(); it++) {
cout << it->first << ": ";
for (auto ait = it->second.begin(); ait!=it->second.end(); ait++) {
cout << *ait << ' ';
}
cout << '\n';
}
这里的输出与预期的完全相同:
12: 67 56
3: 67 56
8: 67 56
7: 67 56
1: 67 56
unordered_set<int> us = ump.find(v[i])->second;
制作集合的副本,这样您的修改就不会更改 ump
中的值。您需要改用引用:
unordered_set<int>& us = ump.find(v[i])->second;
或使用auto
:
auto& us = ump.find(v[i])->second;