Der effizienteste Sortieralgorithmus für eine große Menge von Zahlen

8

Ich arbeite an einem großen Projekt, ich werde mich nicht darum kümmern, es hier zusammenzufassen, aber dieser Teil des Projekts besteht darin, ein sehr großes Textdokument (mindestens etwa 50.000 Wörter (nicht einzigartig)) zu nehmen, und Gib jedes einzelne Wort in der Reihenfolge der am häufigsten verwendeten aus, um es am wenigsten zu verwenden (wahrscheinlich sind die obersten drei "a" "an" und "das").

Meine Frage ist natürlich, was wäre der beste Sortieralgorithmus? Ich habe gelesen, wie ich zähle, und ich mag es, aber meine Sorge ist, dass der Wertebereich im Vergleich zur Anzahl der einzelnen Wörter zu groß ist.

Irgendwelche Vorschläge?

    
aterimperator 05.06.2009, 03:40
quelle

10 Antworten

14

Zuerst benötigen Sie eine Karte des Wortes - & gt; Anzahl. 50.000 Wörter sind nicht viel - es wird leicht in die Erinnerung passen, also gibt es keine Sorgen. In C ++ können Sie die Standard STL std :: map verwenden.

Sobald Sie die Karte haben, können Sie alle Kartenschlüssel in einen Vektor kopieren.

Sortieren Sie diesen Vektor dann mit einem benutzerdefinierten Vergleichsoperator: Vergleichen Sie die Zahlen nicht mit der Karte, anstatt die Wörter zu vergleichen. (Machen Sie sich keine Sorgen um den speziellen Sortieralgorithmus - Ihr Array ist nicht so groß, so dass jede Standardbibliotheks-Sortierung für Sie funktioniert.)

    
Igor Krivokon 05.06.2009, 03:58
quelle
3

Ich würde mit einem Quicksort beginnen und von dort aus weitergehen.

Sehen Sie sich die Wiki-Seite zu Sortieralgorithmen an , um die Unterschiede zu erfahren.

    
Eric 05.06.2009 03:41
quelle
2

Sie sollten versuchen, MSD radix zu sortieren. Es wird Ihre Einträge in lexikographischer Reihenfolge sortieren. Hier ist ein Google-Code-Projekt , für das Sie sich interessieren könnten.

    
JP Alioto 05.06.2009 03:50
quelle
1

Sehen Sie sich den Link an. Eine bildliche Darstellung, wie ein anderer Algorithmus funktioniert. Dies wird Ihnen einen Hinweis geben!

Sortieralgorithmen

    
aJ. 05.06.2009 03:49
quelle
1

Dies ist ein bisschen schwierig, weil Sie eine Karte von Wörtern wollen - & gt; Häufigkeit, und Sie möchten nach dem Wert und nicht nach dem Schlüssel sortieren (was üblich ist). Es gibt ein Java-Beispiel hier , das zeigt, wie es funktioniert ein benutzerdefinierter Vergleicher.

Der bestimmte Algorithmus, den Sie verwenden, wird nicht viel bewirken, also würde ich einfach bei Ihrer Standard-Bibliotheksimplementierung bleiben.

    
Bill the Lizard 05.06.2009 04:06
quelle
1

Sie können eine bessere Leistung als Quicksort mit diesem speziellen Problem erhalten, wenn zwei Wörter die gleiche Anzahl von Malen auftreten, dann spielt es keine Rolle, in welcher Reihenfolge Sie sie ausgeben.

Erster Schritt: Erstellen Sie eine Hash-Map mit den Wörtern als Schlüsselwerte und Häufigkeit als zugehörige Werte. Sie füllen diese Hash-Map beim Analysieren der Datei ein. Achten Sie dabei auf die höchste gefundene Frequenz. Dieser Schritt ist O (n) -Komplexität.

Zweiter Schritt: Erstellen Sie eine Liste mit der Anzahl der Einträge, die der höchsten Häufigkeit des ersten Schritts entspricht. Der Index jedes Slots in dieser Liste enthält eine Liste der Wörter mit der Häufigkeitszählung, die dem Index entspricht. Wörter, die dreimal im Dokument vorkommen, werden beispielsweise in der Liste [3] angezeigt. Iterieren Sie durch die Hash-Karte und fügen Sie die Wörter an den entsprechenden Stellen in der Liste ein. Dieser Schritt ist O (n) -Komplexität.

Dritter Schritt: Iterieren Sie rückwärts durch die Liste und geben Sie alle Wörter aus. Dieser Schritt ist O (n) -Komplexität.

Insgesamt erfüllt dieser Algorithmus Ihre Aufgabe in O (n) time und nicht in O (nlogn), die von quicksort benötigt werden.

    
MahlerFive 05.06.2009 04:14
quelle
1

In fast allen Fällen, die ich je getestet habe, hat Quicksort für mich am besten funktioniert. Ich hatte jedoch zwei Fälle, in denen Combsort der Beste war. Könnte sein, dass Combsort in diesen Fällen besser war, weil der Code so klein war, oder aufgrund einer Eigenart in der Reihenfolge der Daten.

Wenn die Sortierung in meinem Profil angezeigt wird, probiere ich die wichtigsten Arten aus. Ich hatte nie etwas, das sowohl Quicksort als auch Combsort übertraf.

    
Nosredna 05.06.2009 18:38
quelle
0

Ich denke, Sie möchten etwas tun, wie im folgenden Beitrag erläutert:

Ссылка

Sprachen, die das Schließen unterstützen, machen die Lösung sehr einfach, wie LINQ, wie Eric erwähnte.

    
Karephul 05.06.2009 18:31
quelle
0

Bei großen Mengen können Sie beim Informationsabruf die so genannte sortierte Indexierung verwenden, aber für 50.000 Wörter können Sie Folgendes verwenden:

  • liest die gesamte Datei in einen Puffer.
  • parse den Puffer und baue einen Token-Vektor mit struct token {char * term, int termen; } term ist ein Zeiger auf das Wort im Puffer.
  • sortiere die Tabelle nach dem Begriff (lexikographische Reihenfolge).
  • set entrynum = 0, iteriere den Termvektor, Wenn der Ausdruck neu ist, speichern Sie ihn in einem Vektor: struct {char * Begriff; int Frequenz; } Setzen Sie die Frequenz bei Index-Eintragnummer auf 1 und erhöhen Sie die Eintragsnummer, andernfalls erhöhen Sie die Häufigkeit.
  • Sortiere den Vektor nach Häufigkeit in absteigender Reihenfolge.
bill 13.06.2009 09:02
quelle
0

Sie können auch versuchen, digitale Bäume, auch bekannt als Trie, zu implementieren. Hier ist der Link

    
unix_user 28.01.2013 04:41
quelle