【发布时间】:2017-04-26 15:03:58
【问题描述】:
我正在寻找一种在 C++ 中构建多个向量联合的快速方法。
更具体地说:我有一个向量集合(通常是 15-20 vectors 和数千个无符号整数;总是排序且唯一的,因此它们也可以是 std::set)。对于每个阶段,我选择其中的一些(通常是 5-10 个)并构建一个联合向量。比我保存联合向量的长度并选择其他一些向量。这将进行数千次。最后我只对最短联合向量的长度感兴趣。
Small example:
V1: {0, 4, 19, 40}
V2: {2, 4, 8, 9, 19}
V3: {0, 1, 2, 4, 40}
V4: {9, 10}
// The Input Vectors V1, V2 … are always sorted and unique (could also be an std::set)
Choose V1 , V3;
Union Vector = {0, 1, 2, 4, 19, 40} -> Size = 6;
Choose V1, V4;
Union Vector = {0,4, 9, 10, 19 ,40} -> Size = 6;
… and so on …
目前我使用std::set_union,但我相信一定有更快的方法。
vector< vector<uint64_t>> collection;
vector<uint64_t> chosen;
for(unsigned int i = 0; i<chosen->size(); i++) {
set_union(collection.at(choosen.at(i)).begin(),
collection.at(choosen.at(i)).end(),
unionVector.begin(),
unionVector.end(),
back_inserter(unionVectorTmp));
unionVector.swap(unionVectorTmp);
unionVectorTmp.clear();
}
我很感激每一个参考。
编辑 27.04.2017 一个新想法:
unordered_set<unsigned int> unionSet;
unsigned int counter = 0;
for(const auto &sel : selection){
for(const auto &val : sel){
auto r = unionSet.insert(val);
if(r.second){
counter++;
}
}
}
【问题讨论】:
-
如果您只对长度感兴趣,为什么不将长度相加并进行比较,而不是创建将立即丢弃的联合向量?
-
如果你只对最短联合的长度感兴趣,你也许应该重新考虑整个算法,因为可能有比显式构造联合更有效的方法
-
@Rakete1111 这并不容易(几乎),例如1 2 3 和 2 3 4 的并集是 1 2 3 4 并且只有 4 大小
-
@tobi303 没错,错过了这一点 :)
-
你不能。您将需要查看每个元素并确保它是独一无二的。这是可能的,这是 O(V*(N+M)) ,其中 V 是向量的数量,N 和 M 是被联合的向量对的长度。这真的是最好的情况。您也可以通过计数和比较来完成,永远不需要创建联合。
标签: c++ stdvector stdset set-union