Usa set quando:
- Abbiamo bisogno di dati ordinati (elementi distinti).
- Dovremmo stampare / accedere ai dati (in ordine ordinato).
- Abbiamo bisogno del predecessore / successore degli elementi.
Usa unordered_set quando:
- Dobbiamo mantenere un insieme di elementi distinti e non è richiesto alcun ordine.
- Abbiamo bisogno dell'accesso a singolo elemento, cioè senza attraversamento.
Esempi:
impostato:
Ingresso: 1, 8, 2, 5, 3, 9
Uscita: 1, 2, 3, 5, 8, 9
Unordered_set:
Ingresso: 1, 8, 2, 5, 3, 9
Uscita: 9 3 1 8 2 5 (forse questo ordine, influenzato dalla funzione hash)
Principalmente differenza:
Nota: (in alcuni casi set
è più conveniente) ad esempio usando vector
come chiave
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
Il motivo per cui vector<int>
può essere la chiave set
perché vector
override operator<
.
Ma se usi unordered_set<vector<int>>
devi creare una funzione hash per vector<int>
, perché vector non ha una funzione hash, quindi devi definirne una come:
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
}
puoi vedere che in alcuni casi unordered_set
è più complicato.
Principalmente citato da:
https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/
https://stackoverflow.com/a/29855973/6329006