I'm searching for a set container in C++. I want something where I could add elements but they would not repeat more than once and search in that collection would be O(1). What is current defacto cross-compiler container for this now. I seen some in boost (like mpl) and there is one in future c++ standards, but what is best to use now and here?
EDIT
Example of storing vector in boost::unordered_set container. So for me it seems to fit my need pretty well but I will have a lot of data in it so if somebody sees some potential bug right away can you comment on what can go wrong. Again, all elements will be of sorted vector with no pointers.
vector<string> values1;
values1.push_back("aaa");
values1.push_back("bbb");
values1.push_开发者_开发问答back("ccc");
vector<string> values2;
values2.push_back("aa");
values2.push_back("bbb");
values2.push_back("ccc");
vector<string> values3;
values3.push_back("aaa");
values3.push_back("bbb");
vector<string> values4;
values4.push_back("aaa");
values4.push_back("bbb");
values4.push_back("ccc");
values4.push_back("ddd");
vector<string> values5;
values5.push_back("aaa");
values5.push_back("bbb");
values5.push_back("ccc");
vector<string> values6;
values6.push_back("aaa");
values6.push_back("bbb");
values6.push_back("ccc");
values6.push_back("ddd");
boost::unordered_set<vector<string> > collection;
collection.insert(values1); // 1
cout << collection.size() << endl;
collection.insert(values2); // 2
cout << collection.size() << endl;
collection.insert(values3); // 3
cout << collection.size() << endl;
collection.insert(values4); // 4
cout << collection.size() << endl;
collection.insert(values5); // 4
cout << collection.size() << endl;
collection.insert(values6); // 4
cout << collection.size() << endl;
You can use std::unordered_set if you have a C++0x compliant compiler that supports it.
If you are not in that situation, intercepts are available in Microsoft VC++ as stdext::hash_set, or in general using boost::unordered_set. The latter is your best bet for portability at present, pending wider C++0x availability. As noted in the comments by @Nemo, there is widespread support for std::tr1::unordered_set
as well, as an alternative to Boost usage.
[std::set
will be O(log n), as it's based on a search tree. To get O(1), you need to use a hashtable-based container, with due regard to efficient implementation of the hash function for your member objects.]
C++03: boost::unordered_set
C++0x: std::unordered_set
Older implementations (stdext::hash_set
in VC++) are not cross-compilers.
Note: boost::unordered_set
interface has been reused for std::unordered_set
, so the migration is easy too
edit: interesting addition ==> if performance is a worry and you want a quick test for the absence, you might be interested in looking up Bloom Filters.
You need to use a set that is based on a hash-table in order to get O(1) search time (i.e., constant search time), so that would be std::unordered_set
and/or boost::unordered_set
. The current C++03 std::set
and std::multiset
are based on a RB-tree, and therefore have O(log n) search time.
You may also want to have a look at the HashSet class from the Poco C++ libraries.
精彩评论