查找多个向量之间的公共元素(无整数元素)

Find common element between multiple vectors (no integer elements)

本文关键字:元素 整数 向量 之间 查找      更新时间:2023-10-16

是否有一个C++函数可以找到多个向量之间的公共元素?向量元素不是整数(在我的例子中,元素是 QPair 类型(。

理想情况下,该函数将有一组向量作为参数(要比较的向量数量可以变化(并返回向量的公共值。我已经确保每个向量中没有重复项,但可能没有公共元素。

例:

vec 1 [a,b]      vec 2 [c,d,a,e,h]     vec 3 [i,j,a]

要返回的常见值:

a

正如理查德在评论中提到的,交叉可以很容易地用std::set_intersection()完成。前提条件是分类容器。

因此,set_intersection()中的"集合"可以从数学意义上理解——它不限于std::set。也可以使用排序std::vector

要对std::vector进行排序,可以使用std::sort()。在这种情况下,前提条件是元素的可能顺序,即为元素类型定义operator<

QPair定义了一个operator<,如果firstsecond的类型也一样,则可以使用该。

由于OP没有提到QPair哪些类型,我为我的样本isectQPair.cc选择了std::stringdouble

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <QtCore>
int main()
{
// prepare sample data
typedef QPair<std::string, double> Pair;
Pair
a("Hello", 1.23),
b("World", 2.34),
c("Stack", 3.45),
d("Overflow", 4.56),
e("C++11", 5.67),
f("C++14", 6.78),
g("C++17", 7.89),
h("C++20", 8.90),
i("gin hill", 10.1),
j("scheff", 0.0);
std::vector<Pair> vec1({ a, b });
std::vector<Pair> vec2({ c, d, a, e, h });
std::vector<Pair> vec3({ i, j, a });
// sort vectors
std::sort(vec1.begin(), vec1.end());
std::sort(vec2.begin(), vec2.end());
std::sort(vec3.begin(), vec3.end());
// intersect vectors
std::vector<Pair> isect12;
std::set_intersection(
vec1.begin(), vec1.end(), vec2.begin(), vec2.end(),
std::back_inserter(isect12));
std::vector<Pair> isect123;
std::set_intersection(
isect12.begin(), isect12.end(), vec3.begin(), vec3.end(),
std::back_inserter(isect123));
// report
const size_t n = isect123.size();
std::cout << "Intersection contains " << n << " elements"
<< (n ? ':' : '.') << 'n';
for (size_t i = 0; i < n; ++i) {
const Pair &entry = isect123[i];
std::cout << (i + 1) << ".: '" << entry.first
<< "', " << entry.second << 'n';
}
// done
return 0;
}

isectQPair.pro

SOURCES = isectQPair.cc
Qt = core

在Windows 10上的cygwin上编译和测试:

$ qmake-qt5 isectQPair.pro
$ make
$ ./isectQPair
Intersection contains 1 elements:
1.: 'Hello', 1.23
$

在 ideone 上进行现场演示(QPair替换为std::pair(


另一个关于交集的很好的问答可以在这里找到:SO:如何找到两个std::set的交集C++?。

您可以将它们放入哈希表中并将它们计算出来。一旦你再次找到它们,碰撞计数器。如果特定项目的计数器与向量数相同,则您得到了一个交集。无需对对向量进行预排序,定义弱或字符串排序等。

沿着这条线:

#include <iostream>
#include <vector>
#include <list>
#include <unordered_map>
using Qpair = uint32_t; // should be std::pair<int, int> or similar
using Qpairs = std::vector<Qpair>;
int intersections(const std::list<Qpairs>& allpairs) {
std::unordered_map<Qpair, int> m; // element vs counter
auto count = allpairs.size(); // number of vectors to scan
for(const auto& pairs: allpairs) { // loop over all vectors
for (const auto& p : pairs) { // loop over elements in particular vector
m[p] += 1;                // and count them
}
}
int total_count = 0; // how many common elements are here
for (const auto& e : m) {
if (e.second == count) {
++total_count;
// you could add e.first to output vector as well
}
}
return total_count;
}
int main() {
Qpairs v1{ 4, 2, 6, 8, 9 };
Qpairs v2{ 1, 3, 8, 9, 4 };
Qpairs v3{ 2, 8, 9, 5, 0 };
std::list<Qpairs> l{ v1, v2, v3 };
auto q = intersections(l);
std::cout << q << 'n';
return 0;
}