Скопируйте данные std :: map на другую карту - PullRequest
18 голосов
/ 24 февраля 2011

У меня есть карта, которая определена так

 struct A
 {
  int A;
  int B;
 };
 typedef map<int,A> Amap;

Тогда у меня есть Amap1, и я хочу скопировать его в Amap2

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

Иногда это работает правильно, иногда копирует только ключи и значение 0. Где здесь моя ошибка?

Ответы [ 2 ]

39 голосов
/ 24 февраля 2011

Копирование одной карты в другую можно выполнить с помощью оператора = или конструктора копирования.

Например,

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)
15 голосов
/ 24 февраля 2011

Код, который вы разместили выше, будет работать правильно, предполагая, что Amap2 пусто.Если вы попытаетесь insert пара ключ / значение в map, которая уже содержит этот ключ, то старое значение будет сохранено, а новое будет отброшено.По этой причине, если вы напишите

Amap2.insert(Amap1.begin(), Amap1.end());

В некоторых случаях вы можете не копировать все как положено, потому что дублирующиеся ключи не будут копироваться.

Чтобы установить Amap2 равным Amap1, подумайте только об использовании оператора присваивания:

Amap2 = Amap1;

Это, однако, приведет к слепому отбрасыванию содержимого Amap2, поэтому будьте осторожны при этом.

Если вы хотитеЧтобы добавить все пары ключ / значение из Amap2 в Amap1 таким образом, чтобы полностью переопределить существующие пары ключ / значение, вы можете сделать это, используя следующую логику.Идея здесь аналогична логике слияния - мы рассматриваем карты как последовательности отсортированных значений, а затем непрерывно смешиваем их вместе:

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());
}

С этим вы можете написать

MergeMaps(Amap1, Amap2);

Чтобы скопировать все пары ключ / значение из Amap2 в Amap1.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...