Wenn Sie eine haben wirklich große Datei und viele Elemente darin, aber das häufigste Element ist sehr häufig - tritt Bruchteil der Zeit - Sie können es in linearer Zeit mit Platz finden O ( k ) Worte (die Die Konstante in der O ( ) - Notation ist sehr klein (im Grunde genommen 2, wenn Sie den Speicher für Hilfssachen wie Hashing nicht mitzählen). Darüber hinaus funktioniert dies hervorragend mit externem Speicher, da die Datei elementweise nacheinander verarbeitet wird und der Algorithmus niemals "zurückschaut". Ein Weg, dies zu tun, ist über einen klassischen Algorithmus von Misra und Gries, siehe diese Vorlesungsunterlagen>1/kO(k)O(). Das Problem ist jetzt als das Problem der schweren Schläger bekannt (die häufigsten Elemente sind die schweren Schläger).
Die Annahme, dass das häufigste Element Bruchteil der Zeit für k eine kleine Zahl erscheint, mag stark erscheinen, ist aber in gewisser Weise notwendig! Dh, wenn Sie sequentiellen Zugriff auf Ihre Datei haben (und wenn die Datei sehr umfangreich ist, ist der zufällige Zugriff zu teuer), verwendet jeder Algorithmus, der immer das häufigste Element in einer konstanten Anzahl von Durchläufen findet, linearen Raum in der Anzahl der Elemente . Wenn Sie also nichts von der Eingabe annehmen, können Sie eine Hash-Tabelle nicht schlagen. Die Annahme, dass das häufigste Element sehr häufig ist, ist möglicherweise der natürlichste Weg, um die negativen Ergebnisse zu umgehen.>1/kk
Hier ist eine Skizze für , dh wenn es ein einzelnes Element gibt, das mehr als die Hälfte der Zeit auftritt. Dieser Sonderfall ist als Mehrheitswahlalgorithmus bekannt und geht auf Boyer und Moore zurück. Wir behalten ein einzelnes Element und eine einzelne Zählung bei. Initialisieren Sie den Zähler auf 1 und speichern Sie das erste Element der Datei. Verarbeiten Sie dann die Datei in der folgenden Reihenfolge:k=2
- Wenn das aktuelle Element der Datei mit dem gespeicherten Element identisch ist, erhöhen Sie die Anzahl um eins
- Wenn sich das aktuelle Element der Datei vom gespeicherten Element unterscheidet, verringern Sie die Anzahl um eins
- Wenn der aktualisierte Zähler 0 ist, "schmeiße" das gespeicherte Element aus und speichere das aktuelle Element der Datei; Erhöhen Sie die Anzahl auf 1
- Fahren Sie mit dem nächsten Element der Datei fort
Ein bisschen Nachdenken über diese Prozedur wird Sie davon überzeugen, dass, wenn ein "Majoritäts" -Element existiert, dh eines, das mehr als die Hälfte der Zeit auftritt, dieses Element das gespeicherte Element ist, nachdem die gesamte Datei verarbeitet wurde.
Für allgemeines behalten Sie k - 1 Elemente und k - 1 Zählwerte bei und initialisieren die Elemente mit den ersten k verschiedenen Elementen der Datei und den Zählwerten, bis zu der Häufigkeit, mit der jedes dieser Elemente angezeigt wird, bevor Sie das sehenkk−1k−1kk
k−11/kO(k)
k1/kk−1