Użyj zestawu, gdy:
- Potrzebujemy uporządkowanych danych (odrębnych elementów).
- Musielibyśmy wydrukować / uzyskać dostęp do danych (w posortowanej kolejności).
- Potrzebujemy poprzednika / następcy elementów.
Użyj unordered_set, gdy:
- Musimy zachować zestaw odrębnych elementów i nie jest wymagana żadna kolejność.
- Potrzebujemy dostępu do pojedynczego elementu, tj. Bez przechodzenia.
Przykłady:
zestaw:
Wejście: 1, 8, 2, 5, 3, 9
Wyjście: 1, 2, 3, 5, 8, 9
Unordered_set:
Wejście: 1, 8, 2, 5, 3, 9
Wyjście: 9 3 1 8 2 5 (może ta kolejność, na którą ma wpływ funkcja skrótu)
Głównie różnica:
Uwaga: (w niektórych przypadkach set
jest to wygodniejsze) na przykład użycie vector
jako klucza
set<vector<int>> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl; // I have override << for vector
// 1 2
// 1 3
Powodem, dla którego vector<int>
może być kluczem set
bo vector
ręcznym operator<
.
Ale jeśli używasz unordered_set<vector<int>>
, musisz utworzyć funkcję skrótu dla vector<int>
, ponieważ wektor nie ma funkcji skrótu, więc musisz zdefiniować taką:
struct VectorHash {
size_t operator()(const std::vector<int>& v) const {
std::hash<int> hasher;
size_t seed = 0;
for (int i : v) {
seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
};
vector<vector<int>> two(){
//unordered_set<vector<int>> s; // error vector<int> doesn't have hash function
unordered_set<vector<int>, VectorHash> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl;
// 1 2
// 1 3
}
widać, że w niektórych przypadkach unordered_set
jest to bardziej skomplikowane.
Cytowane głównie z:
https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/
https://stackoverflow.com/a/29855973/6329006