![](/img/trans.png)
[英]Is an unordered_set an appropriate data structure for storing vector<int> elements? And if so how would I go about implementing the hash function?
[英]How would I go about comparing a vector with itself, and removing elements according to a comparison function?
我有一个向量v
,我想将其与其他所有元素进行比较。 为了简单起见,在我的示例中,向量由整数组成,比较 function 只是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接受自定义二进制谓词。 因此,如果您为它提供您已经制作的自定义 function,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 以消除排序效果,尽管我不确定 vector->set->vector 转换,需要检查。 但是,如果不支持转换,您仍然可以循环遍历集合并自行构造向量。
总之,你应该能够做到这一点:
set<struct> st=set<struct>(v.begin(), v.end());
vector<struct> uniqvec=vector<struct>(st.begin(), st.end())
如果排序很重要,据我所知,将set<struct>
更改为unordered_set<struct>
应该有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.