提问人:P. H. Allus 提问时间:1/19/2023 最后编辑:P. H. Allus 更新时间:1/19/2023 访问量:83
我将如何将向量与自身进行比较,并根据比较函数删除元素?
How would I go about comparing a vector with itself, and removing elements according to a comparison function?
问:
我有一个向量,我想将每个向量与其他所有元素进行比较。为了简单起见,在我的示例中,向量由整数组成,比较函数简单为 。因此,将不起作用,因为我的真实列表包含一些数据结构。v
if (el1 == el2)
std::unique
下面是我到目前为止尝试过的示例,但它并没有像预期的那样删除所有重复的元素。
#include <iostream>
#include <vector>
#include <algorithm>
bool CompareElements(int el1, int el2)
{
if (el1 == el2) { // Just as an example
return true;
} else {
return false;
}
}
int main()
{
std::vector<int> v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 5, 6, 5};
// Should remove el1 if CompareElements() returns true.
v.erase(
std::remove_if(v.begin(), v.end(), [&](int el1)
{
bool result = false;
std::for_each(v.begin(), v.end(), [&](int el2)
{
result = CompareElements(el1, el2);
});
return result;
}),
v.end()
);
// Print the contents of v
std::cout << "v = {";
for (auto el : v)
std::cout << el << ", ";
std::cout << "}\n";
return 0;
}
重申一下,或其任何变体在这里都行不通,因为我正试图让它与自定义数据结构的向量一起使用,而简单的重复去除器在我的实际程序中不起作用,因此使用用户定义的比较器。删除的顺序无关紧要,我只是想从中删除其中一个比较元素,以便该特定元素不会与其他任何元素进行比较。std::unique
v
我所期望的是这样的
v = {1, 4, 2, 3, 6, 5}
但相反,我得到了
v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 6, }
任何帮助或指示(明白了吗?)将不胜感激!
答:
std::unique 接受自定义二进制谓词。因此,如果您为它提供您已经创建的自定义函数,std::unique 将起作用。
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v = {4, 1, 3, 2, 2, 3, 6, 2, 3, 1, 4, 3, 2, 3, 5, 6, 5};
v.erase(std::unique(v.begin(), v.end(), [](const int a, const int b)
{
return a == b;
}), v.end());
// Print the contents of v
std::cout << "v = {";
for (auto el : v)
std::cout << el << ", ";
std::cout << "}\n";
return 0;
}
如果您提供的类型具有实现的 .operator==
struct Data
{
Data(int _param)
: m_Data{_param}
{}
int m_Data{};
bool operator==(const Data& other) const
{
return m_Data == other.m_Data;
}
};
int main()
{
std::vector<Data> a{ 0,1,1,1,2,3,4,5 };
a.erase(std::unique(a.begin(), a.end()), a.end());
for (auto i : a)
std::cout << i.m_Data << ", ";
return 0;
}
如果时间复杂度对你来说不是什么大问题,你可以将向量转换为集合,然后再转换回向量。该集将删除重复项,您应该保留唯一值。
v=vector<struct>(set<struct>(v.begin(), v.end()));
我相信语法是如此或非常相似。
编辑:有人评论说这是错误的。Set 可以替换为 unordered_set 以消除排序效果,尽管我不确定需要检查的向量->集>向量转换。但是,如果不支持转换,您仍然可以自己遍历集合并构造向量。
总之,您应该能够做到这一点:
set<struct> st=set<struct>(v.begin(), v.end());
vector<struct> uniqvec=vector<struct>(st.begin(), st.end())
如果排序很重要,据我所知,更改为应该有效。set<struct>
unordered_set<struct>
评论
set
{ set<struct> s(v.begin(), v.end()); v = vector<struct>(s.begin(), s.end()); }
评论
result
|=