【问题标题】:C++ Updating values in a unordered_map, where the data type of key-value pair is int-unordered_setC++ 更新 unordered_map 中的值,其中键值对的数据类型为 int-unordered_set
【发布时间】:2021-02-09 10:46:48
【问题描述】:

我正在解决一个 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

我猜这个问题是在将值插入集合的过程中出现的。而且我还认为,问题在某种程度上与“通过参考改变价值观”有关。但不完全确定是什么原因造成的。我进行了更多实验,发现下面的代码 sn-p 有效。但是还是不确定,上面的代码哪里出错了?

在下面的代码 sn-p 中,我没有直接通过它的引用更新集合,而是复制了它。然后插入我的值并再次将其复制到地图中,并且它起作用了。

    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 

【问题讨论】:

标签: c++ pointers stl unordered-map unordered-set


【解决方案1】:
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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2022-12-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多