Wie finden Sie allgemeine Zeichenfolgen zwischen zwei sehr großen Dateien?

8

Ich habe zwei sehr große Dateien (und keiner davon würde in den Speicher passen ). Jede Datei hat eine Zeichenfolge (die keine Leerzeichen enthält und entweder 99/100/101 Zeichen lang ist) in jeder Zeile.

Update: Die Strings sind nicht in einer sortierten Reihenfolge.
Update2: Ich arbeite mit Java unter Windows.

Nun möchte ich den besten Weg finden, alle Strings herauszufinden, die in beiden Dateien vorkommen.

Ich habe darüber nachgedacht, externe merge sort zu verwenden, um beide Dateien zu sortieren und dann einen Vergleich durchzuführen, aber ich bin mir nicht sicher, ob das der beste Weg wäre, dies zu tun. Da die Strings meist ungefähr gleich lang sind, habe ich mich immer gefragt, ob es sinnvoll wäre, für jede Saite eine Art Hash zu berechnen, da dies die Vergleiche zwischen Strings erleichtern würde, aber das würde bedeuten, dass ich die Hashes speichern muss berechnet für die Strings, die ich bisher aus den Dateien gefunden habe, damit sie später beim Vergleich mit anderen Strings verwendet werden können. Ich kann nicht genau sagen, was genau der beste Weg wäre. Ich bin auf der Suche nach Ihren Vorschlägen.

Wenn Sie eine Lösung vorschlagen, geben Sie bitte auch an, ob die Lösung funktionieren würde, wenn mehr als 2 Dateien vorhanden wären und Strings, die in allen vorkommen, herausgefunden werden müssen.

    
Skylark 18.03.2009, 13:58
quelle

8 Antworten

17

Sie haben nicht gesagt, an welcher Plattform Sie arbeiten, also nehme ich an, dass Sie an Windows arbeiten, aber für den unwahrscheinlichen Fall, dass Sie auf einer Unix-Plattform arbeiten, werden Standard-Tools das für Sie tun.

%Vor%     
Leonard 18.03.2009 14:14
quelle
3

Ich würde es wie folgt machen (für beliebig viele Dateien):

  • Sortiere nur 1 Datei (# 1).
  • Gehen Sie durch jede Zeile der nächsten Datei (# 2) und führen Sie eine binäre Suche in der # 1-Datei durch (basierend auf der Anzahl der Zeilen).
  • Wenn Sie die Zeichenfolge finden; schreibe es in eine andere temporäre Datei (# temp1).
  • Nachdem Sie mit # 2 fertig sind, sortieren Sie # temp1 zu # 3 und führen Sie die gleiche Suche durch, diesmal jedoch auf # temp1, nicht auf # 1, was viel weniger als die erste dauern sollte, da nur Zeilen wiederholt werden / li>
  • Wiederholen Sie diesen Vorgang mit neuen temporären Dateien und löschen Sie vorhergehende #temp-Dateien. Jede Iteration sollte immer weniger werden, da die Anzahl der wiederholten Linien abnimmt.
Seb 18.03.2009 14:33
quelle
2

Abhängig davon, wie ähnlich die Einträge in einer Datei sind, könnte es möglich sein, eine Trie zu erstellen (nicht Baum) von ihm. Mit diesem Trie können Sie die andere Datei iterieren und jeden Eintrag überprüfen, wenn er sich im Trie befindet.

Wenn Sie mehr als zwei Dateien haben, durchlaufen Sie eine Datei und erstellen Sie einen neuen Trie aus den Übereinstimmungen. Auf diese Weise enthält der letzte Trie, den Sie haben, alle Übereinstimmungen, die in allen Dateien enthalten sind.

    
martinus 20.03.2009 13:08
quelle
0

Gibt es eine Reihenfolge für die Daten in den Dateien? Der Grund, warum ich frage, ist, dass, obwohl ein Zeilenvergleich eine Ewigkeit dauern würde, eine Datei Zeile für Zeile durchlaufen würde, während eine binäre Suche in der anderen viel schneller wäre. Dies funktioniert jedoch nur, wenn die Daten auf eine bestimmte Art und Weise sortiert sind.

    
Chris Simpson 18.03.2009 14:05
quelle
0

Ich würde beide Dateien in zwei Datenbanktabellen laden, so dass jede Zeichenfolge in der Datei zu einer Zeile in der Tabelle wird und SQL-Abfragen verwenden, um doppelte Zeilen mithilfe einer Verknüpfung zu finden.

    
Jamie Ide 18.03.2009 14:14
quelle
0

Ich würde jede Datei sortieren und dann einen Balanced Line-Algorithmus verwenden, der Zeile für Zeile aus der einen oder anderen Datei liest.

    
mbeckish 18.03.2009 14:43
quelle
0

Eine hashbasierte Lösung könnte so aussehen (in python pseudocode):

%Vor%

Wiederholen Sie den Vorgang und drucken Sie die übereinstimmenden Zeilen:

%Vor%

Es gibt zwei mögliche Probleme.

  1. mögliche Hash-Kollisionen (die teilweise gemildert werden können, aber ein Risiko darstellen.)
  2. muss in der Lage sein, ein dict (assoziatives Array) der Größe zu handhaben: | uniq lines in allen Dateien |

Das ist O (Zeilen * Kosten (md5)).

(wenn Leute eine vollere Python-Implementierung haben, ist es ziemlich einfach zu schreiben, ich kenne Java allerdings nicht!).

    
Gregg Lind 18.03.2009 15:36
quelle
0

Um es in Windows zu tun, ist es ziemlich einfach .. Nehmen wir an, Sie haben zwei Dateien A und B. 'A' Dateien enthält die Zeichenfolgen, die Sie in Datei B suchen möchten. Öffnen Sie einfach die Eingabeaufforderung und verwenden Sie den folgenden Befehl

%Vor%

Dieser Befehl ist ziemlich schnell und kann zwei Dateien sehr effizient vergleichen. Die Datei OUTPUT enthält die in A und B üblichen Zeichenfolgen.

Wenn Sie die ODER-Operationen (Strings in B außer A) ausführen möchten, verwenden Sie

%Vor%     
muzammil butt 08.11.2009 12:58
quelle

Tags und Links