联盟与地图?

时间:2009-08-07 23:06:39

标签: c++ stl

我正在尝试用地图联合两套。我有两套,并希望将它们组合成第三套。我在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);
    }
}

2 个答案:

答案 0 :(得分:10)

数字是一个载体,由字符键入。所以它 - >第二个是矢量。你不能将矢量推送回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());

代码更少,可能更快,或者可能会过多地破坏内存分配器。不确定哪个更好,对于小型集合,性能几乎肯定无关紧要。

带有set的版本也不需要对矢量进行排序,但如果它们更快则会更快。

答案 1 :(得分: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向量本身添加到目标向量中;这种方式只显式复制内容。