如何在 c++ 中计算 2 个不同向量的相等元素
How to count the equal elements of 2 different vectors in c++?
我正在尝试找到一种方法来计算 c++ 中相同大小的 2 个不同向量中有多少元素相等。向量包含结构,我想通过示例中显示的结构的双变量来比较相等性。
并说清楚。我不想检查 2 个向量是否相等,而只想计算它们的元素数量。
以下方法不起作用。它给出地址而不是值。此外,如果我尝试像pointsA[j].dist
一样访问 dist 变量,则会出现错误。
vector<struct PointWithDistance*> pointsA, pointsB;
//the struct
struct PointWithDistance {
Point *p;
double dist;
};
for (int j = 0; j < k; j++){
if (pointsA[j] == pointsB[j])
equalCount++;
}
vector<struct PointWithDistance*> pointsA, pointsB;
你的意思是使用指针吗?如果是这样,您必须执行*(points[A])
(和 b(,因为您当前的比较比较的是指针,而不是它们的内容。
另外,结构Point
是否有operator ==
以便可以对类型进行比较?
你想强制相同的位置吗?比如说,一个向量{1,2,3}
和一个由你的算法{2,3,4}
的向量将有 0 项相等,你想要吗?如果没有,则循环第一个向量,并在每个元素上使用std::find
(如果向量已排序,则std::upper_bound
(到第二个向量。
一些快速代码:
template <typename T=int> struct Point
{
T x,y;
bool operator==(const T& t) { return (x == t.x && y == t.y); }
};
std::vector<Point<>> p1 = {1,2,3};
std::vector<Point<>> p2 = {2,3,4};
for(auto& p : p1)
{
if (std::find(p2.begin(),p2.end(),p) != p2.end())
{
// similar++;
}
}
// or
assert(p1.size() == p2.size());
for(size_t i1 = 0 ; i1 < p1.size() ; i1++)
{
if (p1[i1] == p2[i1])
{
// equal++;
}
}
计算 2 个容器中重复项数的通用解决方案如下所示。如果在容器中找到元素,则使用 std::transform_reduce
添加(std::plus<>{}
(布尔结果。请注意,只要它们包含的类型保持不变,它就可以访问两种不同类型的容器(例如 std::vector<int>
和std::set<int>
(。容器的长度不必相等。有两种 SFINAE 实现可以区分 T
是指针的情况和不是指针的情况:
#include <algorithm> //std::find, std::find_if
#include <cstddef> //std::size_t
#include <functional> //std::plus,
#include <iterator> //std::cbegin, std::cend
#include <numeric> //std::transform_reduce
#include <type_traits> //std::enable_if_t, std::is_pointer_v
namespace {
//core implementation for duplicate_count
template<class C, class F>
std::size_t duplicate_count_impl(const C& container, F pred) {
return std::transform_reduce(std::cbegin(container), std::cend(container), std::size_t{}, std::plus<>{}, pred);
}
}
//returns the number of duplicates in two (different) containers.
//overload for containers where T is a pointer type.
template<typename T, template <typename...> class C1, template <typename...> class C2, std::enable_if_t<std::is_pointer_v<T>>* = nullptr>
std::size_t duplicate_count(const C1<T>& a, const C2<T> &b) {
return duplicate_count_impl(b, [&](T ptr_b) -> bool {
return std::find_if(std::cbegin(a), std::cend(a), [&](T ptr_a) -> bool {
return *ptr_a == *ptr_b;
}) != std::cend(a);
});
}
//returns the number of duplicates in two (different) containers.
//overload for containers where T is not a pointer type.
template<typename T, template <typename...> class C1, template <typename...> class C2, std::enable_if_t<!std::is_pointer_v<T>>* = nullptr>
std::size_t duplicate_count(const C1<T>& a, const C2<T> &b) {
return duplicate_count_impl(b, [&](T n) -> bool {
return std::find(std::cbegin(a), std::cend(a), n) != std::cend(a);
});
}
#include <iostream>
#include <vector>
#include <list>
//[duplicate_count implementations]
struct Point {
int a, b;
bool operator==(const Point& other) const {
return this->a == a && this->b == other.b;
}
};
int main() {
{
std::list<int> v = { 1, 2, 7, 7 };
std::list<int> u = { 0, 1, 2, 7 };
std::cout << "list<int>t number of duplicates: " << duplicate_count(v, u) << 'n';
}
{
auto[a, b, c, d] = std::make_tuple(0, 1, 2, 3);
std::vector<int*> v = { &b, &c, &d, &d };
std::vector<int*> u = { &a, &b, &c, &d };
std::cout << "vector<int*>t number of duplicates: " << duplicate_count(v, u) << 'n';
}
{
auto[a, b, c, d] = std::make_tuple(
Point{ 0, 0 },
Point{ 1, 1 },
Point{ 2, 2 },
Point{ 4, 4 });
std::vector<Point*> v = { &b, &c, &d, &d };
std::vector<Point*> u = { &a, &b, &c, &d };
std::cout << "vector<Point*>t number of duplicates: " << duplicate_count(v, u) << 'n';
}
}
list<int> number of duplicates: 3 vector<int*> number of duplicates: 3 vector<Point*> number of duplicates: 3
您显示的解决方案良好、快速且高效。
它有一些可以轻松解决的小问题。在您的定义vector<struct PointWithDistance*> pointsA, pointsB;
中,变量点 A 和点 B 是向量,包含指向结构的指针。
使用 pointsA[n],您将获得指向该结构的指针。但是你想要结构本身。因此,您只需要取消引用获取的指针即可。由于你想访问结构的成员(通常使用变量.member完成(,你可以使用(*(pointsA[j]((.dist或pointsA[j]->dist。
如果向量的大小保证相同,则只需将代码更新为
vector<struct PointWithDistance*> pointsA, pointsB;
//the struct
struct PointWithDistance {
Point *p;
double dist;
};
for (int j = 0; j < k; j++){
if (pointsA[j]->dist == pointsB[j]->dist)
equalCount++;
}
那是你唯一缺少的东西。
您可以使用 std::inner_product 算法:
#include <iostream>
#include <numeric>
#include <vector>
int main () {
const std::vector a{7, 7, 7, 7};
const std::vector b{7, 6, 7, 7};
const auto equalCount = std::inner_product(
a.begin(), a.end(), b.begin(), 0,
std::plus<>(), std::equal_to<>()
);
std::cout << equalCount << " of the elements are equal.n";
}
输出
3 of the elements are equal.
它是标准内积的概括,使用+
(加号(和==
(equal_to(函数,而不是+
和*
.因此,它计算 0 + (a[0] == b[0]) + (a[1] == b[1]) + ...
.
这利用了false
/true
可以解释为0
/1
的事实。
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 在 C++ 中输出枚举类类型的向量元素
- 用向量的向量元素初始化向量的空向量
- 为什么不允许使用可变长度数组作为向量元素?
- 在函数中传递向量元素
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- 返回向量元素的 l 值的正确方法是什么?
- 当向量增长时,指向向量元素的C++指针是否无效
- 如何在C++中从一个向量元素减去std::unorderede_map向量元素并更新它
- C++:向量元素赋值导致访问冲突
- 将向量元素与字符串元素进行比较,而不初始化向量
- 从2D矢量中找出最小尺寸的向量元素的更好方法
- 当我尝试将一个向量元素的值分配给另一个向量元素时,为什么我的应用程序会崩溃
- 使用递归C++向量元素的总和
- 如何查找为数组中的最低值编制索引的向量元素
- 限制指针访问STL ::向量元素
- 访问索引指向向量元素时的seg故障 - 做错了什么
- 如何使用指针访问向量元素的各个元素
- 向量元素数据损坏了Find()操作
- 将字符值分配给向量元素.C