Verwenden Sie set, wenn:
- Wir benötigen geordnete Daten (verschiedene Elemente).
- Wir müssten die Daten drucken / darauf zugreifen (in sortierter Reihenfolge).
- Wir brauchen Vorgänger / Nachfolger von Elementen.
Verwenden Sie unordered_set, wenn:
- Wir müssen eine Reihe unterschiedlicher Elemente beibehalten, und es ist keine Bestellung erforderlich.
- Wir brauchen Einzelelementzugriff, dh keine Durchquerung.
Beispiele:
einstellen:
Eingabe: 1, 8, 2, 5, 3, 9
Ausgabe: 1, 2, 3, 5, 8, 9
Unordered_set:
Eingabe: 1, 8, 2, 5, 3, 9
Ausgabe: 9 3 1 8 2 5 (möglicherweise diese Reihenfolge, beeinflusst durch die Hash-Funktion)
Hauptunterschied:
Hinweis: (in einigen Fällen set
ist dies bequemer) Verwenden Sie beispielsweise vector
als Schlüssel
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
Der Grund , warum vector<int>
kann als Schlüssel in set
da vector
Überschreibungoperator<
.
Wenn Sie jedoch verwenden unordered_set<vector<int>>
, müssen Sie eine Hash-Funktion für erstellen vector<int>
, da der Vektor keine Hash-Funktion hat. Daher müssen Sie eine wie folgt definieren:
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
}
Sie können das in einigen Fällen sehen unordered_set
komplizierter ist.
Hauptsächlich zitiert von:
https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/
https://stackoverflow.com/a/29855973/6329006