将std :: map数据复制到另一个地图

her*_*ian 18 c++ dictionary stl

我有一个像这样定义的地图

 struct A
 {
  int A;
  int B;
 };
 typedef map<int,A> Amap;
Run Code Online (Sandbox Code Playgroud)

然后我有Amap1,我想复制它Amap2

 A a....;
 Amap Amap1,Amap2;
 Amap1[1]=a1;
 Amap1[2]=a2;
 Amap1[3]=a3;
 Amap2.insert(Amap1.begin(), Amap1.end());
Run Code Online (Sandbox Code Playgroud)

有时这工作正常,有时这只复制键和值0.这里我的错误在哪里?

Arm*_*yan 42

首先,它是__CODE__,而不是__CODE__:)

第二个将一个映射复制到另一个映射可以使用operator =或复制构造函数完成.

例如

map<X, Y> mp1; 
//fill mp1 with data
map<X, Y> mp2(mp1); //mp2 is a copy of mp1 (via copy-construction)
map<X, Y> mp3;
mp3 = mp2; // mp3 is also a copy of mp2 (via copy-assignment)
Run Code Online (Sandbox Code Playgroud)

  • @Wolf:这是一个有争议的问题。Meta 上有很多人问这个问题,我不认为对此有任何共识。我个人认为,如果有实质性的改变,作者应该发布一个全新的答案;使所有现有投票无效似乎是不诚实的,无论意图多么善意。毕竟,他们被要求对_原始_内容/建议进行同行评审。 (2认同)

tem*_*def 15

假设Amap2为空,上面发布的代码将正常工作.如果您尝试将insert键/值对放入map已保存该键的键中,则将保留旧值并丢弃新值.因此,如果你写

Amap2.insert(Amap1.begin(), Amap1.end());
Run Code Online (Sandbox Code Playgroud)

在某些情况下,您可能无法按预期复制所有内容,因为重复的密钥不会复制.

要设置Amap2相等Amap1,请考虑使用赋值运算符:

Amap2 = Amap1;
Run Code Online (Sandbox Code Playgroud)

Amap2但是,这会盲目地丢弃内容,所以在这样做时要小心.

如果你想要做的是增加从所有键/值对Amap2Amap1在完全覆盖现有的键/值对的方式,你可以这样做使用下面的逻辑.这里的想法类似于mergesort背后的逻辑 - 我们将地图视为排序值的序列,然后将两者连续混合在一起:

void MergeMaps(map<int, A>& lhs, const map<int, A>& rhs) {
    map<int, A>::iterator lhsItr = lhs.begin();
    map<int, A>::const_iterator rhsItr = rhs.begin();

    while (lhsItr != lhs.end() && rhsItr != rhs.end()) {
        /* If the rhs value is less than the lhs value, then insert it into the 
           lhs map and skip past it. */
        if (rhsItr->first < lhsItr->first) {
            lhs.insert(lhsItr, *rhsItr); // Use lhsItr as a hint.
            ++rhsItr;
        }
        /* Otherwise, if the values are equal, overwrite the lhs value and move both
           iterators forward. */
        else if (rhsItr->first == lhsItr->first) {
            lhsItr->second = rhsItr->second;
            ++lhsItr; ++rhsItr;
        }
        /* Otherwise the rhs value is bigger, so skip past the lhs value. */
        else
            ++lhsItr;

    }

    /* At this point we've exhausted one of the two ranges.  Add what's left of the
       rhs values to the lhs map, since we know there are no duplicates there. */
    lhs.insert(rhsItr, rhs.end());
}
Run Code Online (Sandbox Code Playgroud)

有了这个,你可以写

MergeMaps(Amap1, Amap2);
Run Code Online (Sandbox Code Playgroud)

要将所有键/值对从复制Amap2Amap1.

希望这可以帮助!

  • 如果我想确保现有密钥被覆盖,我可以选择两个选项:我要么使用std :: copy而不是`std :: inserter`我会编写一个使用`operator []`的自定义密钥.替代2线程虽然可能不那么有效,但是复制rhsItr然后将常规插入lhsItr复制到副本然后交换. (2认同)