我需要像std :: vector或std :: list这样的数据结构,其元素将是唯一的。在大多数情况下,我会在其上调用push_back,有时甚至会擦除它们。当我插入已经存在的元素时,需要通过布尔值或异常通知我。
它应该具有的最重要的属性:插入顺序。每次迭代时,它都应按插入顺序返回元素。
我们可以用另一种方式思考:一个保证元素唯一性的队列。但是我不想弹出元素,而是想像对vector或list一样对它们进行迭代。
什么是我需要的最佳数据结构?
答案 0 :(得分:0)
您可以使用std::set
在调用pair<iterator,bool>
方法时,它将返回一对insert
。如果该元素已存在于集合中,则该对中的布尔值为false(在这种情况下将不会添加该元素)。
答案 1 :(得分:0)
使用带有常规std :: vector和std :: set的结构。
当您按下按钮时,请检查该集合是否存在该元素。当您需要迭代时,请遍历向量。如果您需要从向量中删除,也请从集合中删除。
基本上,仅将集合用作备用,仅用于快速的“元素存在”检查。
// either make your class a template or use a fixed type of element
class unique_vector
{
public:
// implement the various operator you need like operator[]
// alternatively, consider inheriting from std::vector
private:
std::set<T> m_set; // fast lookup for existence of elements
std::vector<T> m_vector; // vector of elements
};
答案 2 :(得分:0)
我更喜欢使用std :: unordered_set将现有元素存储在std :: vector中,并且其查找时间为O(1)更快,而std :: set的查找时间为O(logn)。>
答案 3 :(得分:0)
您可以为此使用Boost.MultiIndex:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
using namespace boost::multi_index;
template<typename T>
using unique_list=multi_index_container<
T,
indexed_by<
sequenced<>,
hashed_unique<identity<T>>
>
>;
#include <iostream>
int main()
{
unique_list<int> l;
auto print=[&](){
const char* comma="";
for(const auto& x:l){
std::cout<<comma<<x;
comma=",";
}
std::cout<<"\n";
};
l.push_back(0);
l.push_back(1);
l.push_back(2);
l.push_back(0);
l.push_back(2);
l.push_back(4);
print();
}
输出
0,1,2,4