2010-09-03 2 views
48

Как слить две карты STL в одну? Оба они имеют одинаковые ключевые значения (карта). Если есть перекрытие клавиш, я бы хотел отдать предпочтение одной из карт.Объединить две карты STL

ответ

91

Предполагая, что вы хотите сохранить элементы в МАПО, и объединить элементы в mapB для которых нет никакого ключа в МАПО:

mapA.insert(mapB.begin(), mapB.end()) 

будет делать то, что вы хотите, я думаю.

EDIT: добавление рабочий пример

#include <iostream> 
#include <map> 

void printIt(std::map<int,int> m) { 
    for(std::map<int,int>::iterator it=m.begin();it!=m.end();++it) 
     std::cout << it->first<<":"<<it->second<<" "; 
    std::cout << "\n"; 
} 

int main() { 
    std::map<int,int> foo,bar; 
    foo[1] = 11; foo[2] = 12; foo[3] = 13; 
    bar[2] = 20; bar[3] = 30; bar[4] = 40; 
    printIt(foo); 
    printIt(bar); 
    foo.insert(bar.begin(),bar.end()); 
    printIt(foo); 
    return 0; 
} 

выход:

:!./insert 
1:11 2:12 3:13 
2:20 3:30 4:40 
1:11 2:12 3:13 4:40 
+0

Я не вижу, как это не отменяет дубликат в mapA, если ключи совпадают. Если я просто скажу, что mapB был моей «предпочтительной» картой, я мог бы использовать это, я думаю. Таким образом, если это дубликат, тогда ключевым в mapB будет тот, который в конечном итоге заканчивается на новой карте (которая теперь является mapA). Правильно ли это, или я не понимаю, что такое вставка, когда есть дубликат? – JonF

+9

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

+0

о, я вижу. к сожалению, он не строится. Он генерирует огромное сообщение об ошибке – JonF

22

Если вы хотите скопировать данные с одной карты на другую, вы можете использовать std::map «s insert:

targetMap.insert(sourceMap.begin(), sourceMap.end()); 

Обратите внимание, что insert не обновляет элементы, если их k ey уже находится в targetMap; эти элементы будут оставлены как есть. Для замены элементов, вы должны скопировать в явном виде, например:

for(auto& it : sourceMap) 
{ 
    targetMap[it.first] = it.second; 
} 

Если вы не против потери данных в sourceMap, другой способ достижения копирования и перезапись является insert цели в источник и std::swap результаты:

sourceMap.insert(targetMap.begin(), targetMap.end()); 
std::swap(sourceMap, targetMap); 

После замены, sourceMap будет содержать targetMap «s старые данные, и targetMap будет слияние двух карт, с предпочтением sourceMap» s записей.

1

В соответствии с ISO/IEC 14882: 2003, раздел 23.1.2, таблица 69, выражение a.insert (I, J):

до: I, J не итератора в. вставляет каждый элемент из диапазона [i, j) тогда и только тогда, когда нет элемента с ключом, эквивалентным ключу этого элемента в контейнерах с уникальными ключами;

С этой целью std :: map следует за этим ограничением, если вы хотите отдать предпочтение «значениям» с одной карты над другой, которую вы должны вставить в нее. Например,

std::map<int, int> goodKeys; 
std::map<int, int> betterKeys; 

betterKeys.insert(goodKeys.begin(), goodKeys.end()); 

Так что, если есть какие-либо эквивалентные ключи в goodKeys и betterKeys, «ценность» в betterKeys будет сохранен.

Смежные вопросы