我的vector<vector<int> > A;
大小为44,000。现在我需要将'A'与另一个向量相交:vector<int> B
,大小为400,000。 A矢量的内部矢量的大小是可变的,并且最大大小为9,000个元素,我使用以下代码:
for(int i=0;i<44000;i++)
vector<int> intersect;
set_intersection(A[i].begin(),A[i].end(),B.begin(),B.end(),
std::back_inserter(intersect));
我是否有某种方法可以使代码高效。矢量A中的所有元素都被排序,即它们的形式为((0,1,4,5),(7,94,830,1000)), etc
。也就是all elements of A[i]'s vector < all elements of A[j]'s vector if i<j.
编辑:我想到的解决方案之一是使用以下方法将所有A [i]合并到另一个向量mergedB中:
vector<int> mergedB;
for(int i=0;i<44000;i++)
mergedB.insert(mergedB.begin(),mergedB.end(),A[i])
vector<int> intersect;
set_intersection(mergedB.begin(),mergedB.end(),B.begin(),B.end(),
std::back_inserter(intersect));
但是,我没有理由为什么我的两个代码的性能几乎相同。有人可以帮我理解这个
答案 0 :(得分:1)
碰巧,set_itersection
很容易写。
一种奇特的方法是创建一个连接迭代器,并遍历lhs向量的每个元素。但手动编写set_intersection
更容易。
template<class MetaIt, class FilterIt, class Sink>
void meta_intersect(MetaIt mb, MetaIt me, FilterIt b, FilterIt e, Sink sink) {
using std::begin; using std::end;
if (b==e) return;
while (mb != me) {
auto b2 = begin(*mb);
auto e2 = end(*mb);
if (b2==e2) {
++mb;
continue;
}
do {
if (*b2 < *b) {
++b2;
continue;
}
if (*b < *b2) {
++b;
if (b==e) return;
continue;
}
*sink = *b2;
++sink; ++b; ++b2;
if (b==e) return;
} while (b2 != e2);
++mb;
}
}
这不会复制元素,而不是复制到输出向量中。它假设MetaIt
是容器的迭代器,FilterIt
是兼容容器的迭代器,Sink
是输出迭代器。
我试图删除所有冗余比较,同时保持代码可读性。有一个冗余检查 - 在我们用完rhs内容的单个案例中检查b!=e
然后b==e
。因为这应该只发生一次,清晰度的成本是不值得的。
您可以通过现代硬件上的矢量化使上述效率更高。我不是那方面的专家。将矢量化与元迭代混合是很棘手的。
答案 1 :(得分:0)
由于您的向量已排序,因此最简单,最快的算法将是