2009-08-07 93 views
1

我想聯合兩套地圖。我有兩套,並希望將它們組合成第三套。我在push_back中得到了這段代碼的錯誤。有沒有辦法做到這一點?與地圖聯盟?

map<char, vector<char> > numbers; 
map<char, vector<char> >::iterator it; 
numbers['E'].push_back('a');//set1 
numbers['E'].push_back('b'); 
numbers['E'].push_back('c'); 
numbers['G'].push_back('d');//set2 
numbers['G'].push_back('e'); 


void Create::Union(char set1, char set2, char set3) 
{ 
    for (it = numbers.begin(); it != numbers.end(); ++it) 
    { 
     numbers[set3].push_back(it->second); 
    } 
} 
+0

你會得到哪個錯誤? – sth 2009-08-07 23:09:56

+0

爲什麼使用矢量當你可以使用集? – 2009-08-08 00:53:59

回答

3

我想你可能想:

void Create::Union(char set1, char set2, char set3) 
{ 
    vector<char> &target = numbers[set3]; 
    for (it = numbers.begin(); it != numbers.end(); ++it) 
    { 
     if (&it->second == &target) 
      continue; // Don't insert into ourselves 
     target.insert(target.end(), it->second.begin(), it->second.end()); 
    } 
} 

push_back試圖添加item->second矢量本身到目標向量;這種方式只顯式複製內容。

+0

迭代器達到數字[set3]時會發生什麼,並且您嘗試將其插入到自身中? – 2009-08-07 23:13:13

+0

(真正的問題,順便說一句,我實際上並不知道答案,我懷疑它是「壞東西」,因爲矢量可能會在中途調整大小)。 +1爲一般的想法,假設我錯了,或者你會把它整理出來。 – 2009-08-07 23:18:43

+1

@onebyone,好點。修改向量會使.begin()和.end()迭代器無效,因此它是未定義的行爲 – bdonlan 2009-08-07 23:24:09

10

數字是載體的載體,按字符鍵。所以它 - >第二個是矢量。你不能將一個向量push_back到一個char向量中。

您應該迭代數字[set1]和數字[set2],而不是迭代數字。或者正如bdonlan所說,你可以插入一個範圍,儘管他將所有數字聯合起來,而不僅僅是set1和set2。

另請參見:其中的item定義?你的意思是it

另外,請注意,push_back不檢查值是否已經在向量中。因此,一旦你清楚瞭解這個通用方法的細節,你的例子就會起作用,'E'和'G'的聯合將是一個包含'a','b','c','d'的向量, 'E'。但是如果你把'a','b','c'與'c','d','e'結合在一起,你會得到'a','b','c','c', 'd','e',這可能不是你想要的工會。

假設你的矢量總是要進行排序,你可以改用標準算法set_union:

#include <algorithm> 
#include <iterator> 

... 

numbers[set3].clear(); 
std::set_union(numbers[set1].begin(), numbers[set1].end(), 
       numbers[set2].begin(), numbers[set2].end(), 
       std::back_inserter(numbers[set3])); 

如果你想利用一切的工會數字,我可能會跟要麼去:

vector<char> sofar; 
map<char, vector<char> >::iterator it; 
for (it = numbers.begin(); it != numbers.end(); ++it) { 
    // new, empty vector 
    vector<char> target; 
    // merge everything so far with the next item from the map, 
    // putting the results in target 
    set_union(sofar.begin(), sofar.end(), 
       it->second.begin(), it->second.end(), 
       back_inserter(target)); 
    // the result is the new "everything so far" 
    // note that this operation is very fast. It doesn't have to 
    // copy any of the contents of the vector, just exchange some pointers. 
    swap(target, sofar); 
} 
// replace numbers[set3] with the final result 
swap(numbers[set3], sofar); 

或者:

set<char> sofar; 
map<char, vector<char> >::iterator it; 
for (it = numbers.begin(); it != numbers.end(); ++it) { 
    // let std::set remove the duplicates for us 
    sofar.insert(it->second.begin(), it->second.end()); 
} 
// replace numbers[set3] with the final result 
numbers[set3].clear(); 
numbers[set3].insert(numbers[set3].end(), sofar.begin(), sofar.end()); 

這是更少的代碼,可能是FAS ter,或者可能會過多地分配內存分配器。不知道哪個更好,對於小型收藏品的表現幾乎肯定不重要。

set的版本也不需要向量進行排序,雖然它的速度更快。

+4

+1使用可用的STL函數獲得更清晰的代碼。我看到很多程序員在編寫他們自己的實現時跳過,而沒有調查STL中已有的東西。 – Kei 2009-08-07 23:39:14