C ++ 0x introduit unordered_set
ce qui est disponible dans boost
et dans de nombreux autres endroits. Ce que je comprends, c'est qu'il unordered_set
s'agit d'une table de hachage avec une O(1)
complexité de recherche. D'un autre côté, ce set
n'est rien d'autre qu'un arbre avec une log(n)
complexité de recherche. Pourquoi diable quelqu'un utiliserait-il à la set
place de unordered_set
? c'est à dire y a-t-il un besoin de set
plus?
145
Réponses:
Quand, pour quelqu'un qui souhaite parcourir les éléments de l'ensemble, l'ordre compte.
la source
< >
?Les postes non ordonnés doivent payer leur temps d'accès moyen O (1) de plusieurs manières:
set
utilise moins de mémoire queunordered_set
pour stocker le même nombre d'éléments.set
peuvent être plus rapides que les recherches dans un fichierunordered_set
.unordered_set
, ils sont souvent assurés d'avoir de meilleures pires complexité des cas pourset
(par exempleinsert
).set
trie les éléments est utile si vous souhaitez y accéder dans l'ordre.set
s avec<
,<=
,>
et>=
.unordered_set
ne sont pas tenus de soutenir ces opérations.la source
<
).Chaque fois que vous préférez un arbre à une table de hachage.
Par exemple, les tables de hachage sont "O (n)" dans le pire des cas. O (1) est le cas moyen. Les arbres sont au pire "O ( log n)".
la source
Utilisez set lorsque:
Utilisez unordered_set lorsque:
Exemples:
ensemble:
Entrée: 1, 8, 2, 5, 3, 9
Sortie: 1, 2, 3, 5, 8, 9
Unordered_set:
Entrée: 1, 8, 2, 5, 3, 9
Sortie: 9 3 1 8 2 5 (peut-être cet ordre, influencé par la fonction de hachage)
Principalement différence:
Remarque: (dans certains cas,
set
c'est plus pratique) par exemple en utilisantvector
comme cléLa raison pour laquelle
vector<int>
peut être aussi cléset
que levector
remplacementoperator<
.Mais si vous utilisez,
unordered_set<vector<int>>
vous devez créer une fonction de hachage pourvector<int>
, car vector n'a pas de fonction de hachage, vous devez donc en définir une comme:vous pouvez voir que dans certains cas,
unordered_set
c'est plus compliqué.Principalement cité à partir de: https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/ https://stackoverflow.com/a/29855973/6329006
la source
Parce que std :: set fait partie du C ++ standard et unordered_set ne l'est pas. C ++ 0x n'est PAS un standard, et Boost non plus. Pour beaucoup d'entre nous, la portabilité est essentielle, ce qui signifie s'en tenir à la norme.
la source
Considérez les algorithmes Sweepline. Ces algorithmes échoueraient complètement avec les tables de hachage, mais fonctionneraient parfaitement avec des arbres équilibrés. Pour vous donner un exemple concret d'algorithme sweepline, considérons l'algorithme de fortune. http://en.wikipedia.org/wiki/Fortune%27s_algorithm
la source
Encore une chose, en plus de ce que d'autres personnes ont déjà mentionné. Bien que la complexité après amortissement prévu pour l' insertion d' un élément à un unordered_set est O (1), chaque maintenant et il va prendre O (n) parce que les besoins de table de hachage à restructurées (le nombre de seaux besoins de changement) - même avec une «bonne» fonction de hachage. Tout comme l'insertion d'un élément dans un vecteur prend O (n) de temps en temps car le tableau sous-jacent doit être réalloué.
L'insertion dans un ensemble prend toujours au plus O (log n). Cela peut être préférable dans certaines applications.
la source
Pardonnez-moi, encore une chose à noter à propos de la propriété triée:
Si vous voulez une plage de données dans le conteneur, par exemple: Vous avez stocké l'heure dans l' ensemble et vous voulez une heure du 01/01/2013 au 01/01/2014.
Pour unordered_set, c'est impossible.
Bien sûr, cet exemple serait plus convaincant pour les cas d'utilisation entre map et unordered_map .
la source
g++
6.4 Stdlibc ++ Benchmark ordonné vs non ordonnéJ'ai comparé cette implémentation Linux C ++ dominante pour voir la différence:
Les détails et l'analyse complets du benchmark ont été donnés à l' adresse : Quelle est la structure de données sous-jacente d'un ensemble STL en C ++? et je ne les répéterai pas ici.
"BST" signifie "testé avec
std::set
et" hash map "signifie" testé avecstd::unordered_set
. "Heap" est pourstd::priority_queue
lequel j'ai analysé à: Heap vs Binary Search Tree (BST)En résumé:
le graphique montre clairement que dans ces conditions, l'insertion de hashmap était toujours beaucoup plus rapide lorsqu'il y avait plus de 100k éléments, et la différence augmente à mesure que le nombre d'éléments augmente
Le coût de cette augmentation de vitesse est que vous n'êtes pas en mesure de traverser efficacement dans l'ordre.
les courbes suggèrent clairement que ordonné
std::set
est basé sur BST etstd::unordered_set
est basé sur hashmap. Dans la réponse de référence, j'ai en outre confirmé cela en déboguant le code par étape GDB.Question similaire pour
map
vsunordered_map
: y a-t-il un avantage à utiliser map sur unordered_map en cas de clés triviales?la source
Au loin, je dirais qu'il est pratique d'avoir des choses dans une relation si vous cherchez à le convertir dans un format différent.
Il est également possible que si l'accès est plus rapide, le temps de construction de l'index ou la mémoire utilisée lors de sa création et / ou de son accès soit plus long.
la source
Si vous voulez que les choses soient triées, vous utiliserez set au lieu de unordered_set. unordered_set est utilisé sur set lorsque la commande stockée n'a pas d'importance.
la source
Bien que cette réponse ait peut-être 10 ans de retard, il convient de souligner qu'elle
std::unordered_set
présente également des inconvénients en matière de sécurité.Si la fonction de hachage est prévisible (c'est généralement le cas sauf si elle applique des contre-mesures telles qu'un sel aléatoire), les attaquants peuvent fabriquer à la main des données qui produisent des collisions de hachage et font que toutes les insertions et recherches prennent O (n) temps .
Cela peut être utilisé pour des attaques par déni de service très efficaces et élégantes.
De nombreuses (la plupart?) Implémentations de langages qui utilisent en interne des cartes de hachage se sont heurtées à ceci:
la source