c++ - unordered_map Komplexität
Muss ich erstellen Sie eine lookup-Funktion, wenn ein (X,Y) - paar entspricht einem bestimmten Z-Wert. Eine wichtige Voraussetzung dafür ist, dass ich brauchen, um es in als in der Nähe der O(1) Komplexität, wie ich kann. Mein plan ist die Verwendung einer unordered_map.
Ich in der Regel verwenden Sie nicht eine hash-Tabelle nachschlagen, wie die lookup-Zeit war nie wichtig für mich. Bin ich richtig in der Annahme, dass, solange ich baute die unordered_map mit keine Kollisionen, mein lookup-Zeit von O(1)?
Meine Sorge ist dann, was die Komplexität wird, wenn dort der Schlüssel nicht vorhanden ist, die in der ungeordneten map. Wenn ich unordered_map::find (): zum Beispiel, um festzustellen, ob ein Schlüssel vorhanden ist, in meinem hash-Tabelle, wie wird es gehen, darum, mir eine Antwort? Tut es eigentlich iteriert über alle Schlüssel?
Ich bin sehr dankbar für die Hilfe.
InformationsquelleAutor user1764386 | 2013-03-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Standard erfordert mehr oder weniger mit Eimer für Kollision
Auflösung, was bedeutet, dass die tatsächlichen look-up-Zeit
wahrscheinlich werden linear mit Bezug auf die Anzahl der Elemente in der
Eimer, unabhängig davon, ob das element vorhanden ist oder nicht.
Es ist möglich zu machen, O(lg N), aber es ist in der Regel nicht getan,
da die Anzahl der Elemente im bucket sollte klein,
wenn der hash-Tabelle richtig verwendet wird.
Sicherzustellen, dass die Anzahl der Elemente in einem Eimer ist klein, Sie
müssen sicherstellen, dass die hashing-Funktion ist wirksam. Was
effektiv bedeutet, hängt vom Typen und Werte als Hash.
(Die MS-Implementierung verwendet FNV, das ist einer der besten
generische hashs um, aber wenn Sie haben Besondere Kenntnisse in der
die tatsächlichen Daten, die Sie sehen werden, könnten Sie in der Lage, besser zu tun.)
Eine andere Sache, die helfen können, reduzieren Sie die Anzahl der Elemente pro
bucket ist die Kraft mehr die Eimer oder verwenden Sie eine kleinere load-Faktor.
Für die erste, die Sie übergeben können, die minimale anfängliche Zahl von
Eimer, als argument an den Konstruktor übergeben. Wenn Sie wissen, die
Gesamtanzahl von Elementen in der Karte, können Sie
Kontrolle der Auslastung auf diese Weise. Sie können auch ein Mindestmaß forse
Anzahl der Gruppen, sobald die Tabelle gefüllt worden ist, durch den Aufruf
rehash
. Ansonsten gibt es eine Funktionstd::unordered_map<>::max_load_factor
die Sie verwenden können. Esist nicht garantiert, etwas zu tun, aber in jedem vernünftigen
Umsetzung, es wird. Beachten Sie, dass wenn Sie es verwenden, auf einem bereits
gefüllt
unordered_map
sind, werden Sie wahrscheinlich haben, um Anrufunordered_map<>::rehash
danach.(Es gibt mehrere Dinge, die ich nicht verstehe, über die standard -
unordered_map: warum der load-Faktor ist ein
float
stattdouble
; warum ist es nicht erforderlich, um einen Effekt zu haben; und warum esnicht automatisch aufrufen
rehash
für Sie.)InformationsquelleAutor James Kanze
Um keine Kollisionen in der Hash-Datenstruktur ist unglaublich schwierig (wenn nicht unmöglich, für einen gegebenen hash-Funktion und jede Art der Daten). Es würde auch eine Tabelle der Größe genau gleich der Anzahl der Tasten. Nein, es muss nicht so streng. Solange die hash-Funktion verteilt die Werte in eine relativ einheitliche Weise haben Sie
O(1)
lookup Komplexität.Hash-Tabellen sind in der Regel nur arrays mit verknüpften Listen kümmert sich um die Kollisionen (dies ist der chaining-Methode - es gibt andere Methoden, aber diese ist wahrscheinlich die am meisten verwendeten Umgang mit Kollisionen). So, um herauszufinden, ob ein Wert enthalten ist, in einem Eimer, wird es (möglicherweise) zu einer Iteration über alle Werte in diesem Eimer. Also, wenn die hash-Funktion gibt Ihnen eine gleichmäßige Verteilung, und es gibt
N
Eimer, und insgesamtM
Werte, sollte es (im Durchschnitt)M/N
Werte pro Eimer. Solange dieser Wert nicht zu groß ist, ermöglicht dieseO(1)
lookup.So, wie eine etwas langatmige Antwort auf deine Frage, solange die Hash-Funktion sinnvoll ist, erhalten Sie
O(1)
lookup, es zu Durchlaufen (durchschnittlich)O(M/N)
Tasten geben Sie ein "negatives" Ergebnis.InformationsquelleAutor Yuushi
Wie bei jedem hash-Tabelle, der Schlimmste Fall ist immer die lineare Komplexität (Edit: wenn du gebaut hast, die Karte ohne irgendwelche Kollisionen, wie Sie erklärte in Ihrem ursprünglichen Beitrag, dann wirst du nie sehen, in diesem Fall):
http://www.cplusplus.com/reference/unordered_map/unordered_map/find/
Jedoch, da eine unordered_map kann nur die eindeutigen Schlüssel, sehen Sie die Durchschnittliche Komplexität der Konstanten Zeit (container wird zuerst überprüft hash-index, und dann iteriert über die Werte auf diesem index).
Ich denke, dass die Dokumentation für unordered_map::count Funktion ist informativer:
Nun, finden Sie wieder etwas wenn es nicht mehr zurück können Sie einen iterator, um Ihren Wert, so unordered_map::end war die beste Wahl.
vielen Dank für die Hilfe. Ich meinte, ich bin etwas verwirrt von seiner Antwort, weil ich es interpretieren zu bedeuten, dass die Komplexität wird besser sein als O(N), wenn der Schlüssel nicht in die unordered_map.
im Durchschnitt wird es sein. Wenn Sie sehen, die unwahrscheinlichen schlimmsten Fall alle Ihre Eingänge hashing auf den gleichen Wert, dann wird die Datenstruktur muss iteriert über die gesamte Liste.
Würden Sie bitte erklären im detail? Kann ich vermeiden, dass zwei beliebige Tasten Zuordnung, um den gleichen Wert? Ich bin Gebäude die unordered_map zu einer Zeit, basiert auf der Eingabe von Daten. Ich bin nie hinzufügen, um es später.
InformationsquelleAutor AndyG