Schneller Datenstruktur für das suchen nach einem string
Habe ich diesen code, der bestimmt, ob ein Wort (ignoring case) enthalten ist in einer wordList text-Datei. Aber die wordList text-Datei 65000++ Linien, und Suche einfach ein Wort über meine Implementierung unten fast eine minute dauert. Könnten Sie sich vorstellen, dass es eine bessere Umsetzung?
Dank!
import java.io.*;
import java.util.*;
public class WordSearch
{
LinkedList<String> lxx;
FileReader fxx;
BufferedReader bxx;
public WordSearch(String wordlist)
throws IOException
{
fxx = new FileReader(wordlist);
bxx = new BufferedReader(fxx);
lxx = new LinkedList<String>();
String word;
while ( (word = bxx.readLine()) != null)
{
lxx.add(word);
}
bxx.close();
}
public boolean inTheList (String theWord)
{
for(int i =0 ; i < lxx.size(); i++)
{
if (theWord.compareToIgnoreCase(lxx.get(i)) == 0)
{
return true;
}
}
return false;
}
}
- Leerzeichen Hafen besser in allen Editoren (einschließlich der SO ist wie Magie, textarea) für Einzüge als tabs.
- wie viele unterschiedliche Wörter gibt es?
- Wo können wir eine lange Liste von Wörtern? Ich Schaffe es, zu simulieren, 15k und ich bin in einer ms
- gutenberg.org/wiki/Main_Page erhalten Sie einige große Texte, die Sie nutzen können.
- und ich war kämpfen, um etwas aus einer html-Datei 😛
Du musst angemeldet sein, um einen Kommentar abzugeben.
Verwenden
HashSet
in dem du eine Kleinbuchstaben-version von jedem Wort. Überprüfen, ob einHashSet
enthält eine angegebene Zeichenfolge ist, im Durchschnitt eine Konstante Zeit (gelesen: extrem schnell) - operation.Da bist du auf der Suche, möchten Sie vielleicht zu prüfen, Sortierung der Liste, bevor die Suche; dann kann man die Binärsuche ist viel schneller als lineare Suche. Das kann helfen, wenn Sie führen Sie mehrere Suchvorgänge auf der gleichen Liste, andernfalls wird die Strafe, die Sie zahlen, um die Liste zu Sortieren, ist nicht Wert, es für die Suche nur einmal.
Auch tun linearen Suche, die auf eine verknüpfte Liste mit "lxx.Holen(i)" ist nach ärger. LinkedList.get() ist O(n). Sie können entweder einen Iterator (einfache Möglichkeit: for (String s : lxx)), oder wechseln Sie zu einer Liste geben, die O(1) Zugriffszeit, wie ArrayList.
Jeder Suche durch
l
in O(n) - operation, also das wird ziemlich teuer, wenn Sie haben Tausende von Worten. Verwenden Sie stattdessen eineHashSet
:und verwenden Sie dann
lxx.contains(theWord.toLowerCase())
um zu überprüfen, ob das Wort in der Datei.Jede Suche in der
HashSet
ist eine O(1) operation, so dass die Zeit es dauert, ist (fast) unabhängig von der Größe der Datei.First off, nicht deklarieren Sie eine variable, um eine LinkedList, erklären, dass es eine Liste (code-Teile nicht mit der Liste gelöscht:
Nächsten nicht nennen, kommen auf die Liste, verwenden Sie eine LinkedList zu bekommen wird SEHR langsam sein. Verwenden Sie stattdessen einen iterator... besser noch die Verwendung der neuen stype for-Schleife, die mit einem iterator für Sie:
Nächsten änderung die neue LinkedList in eine neue ArrayList:
lxx = new ArrayList();
Dieser code sollte schneller sein, aber Sie können noch besser zu machen.
Da Sie nicht zu kümmern doppelte Wörter verwenden, anstatt eine Liste und verwenden Sie ein HashSet statt einer ArrayList.
Tun, dass die Geschwindigkeit des Programms deutlich.
Deinen original-code, mit einer LinkedList mit bekommen hat, zu beginnen am Anfang der Liste jedes mal, wenn der Suche nach dem nächsten Wort in der Liste. Mit dem Iterator (via der neue Stil for-each-Schleife) hält, dass aus geschieht.
Verwendung einer LinkedList bedeutet, dass jedes mal, wenn Sie gehen müssen, um das nächste Wort in der Liste wird ein lookup beteiligten, die ArrayList nicht haben, dass overhead.
Verwendung eines HashSet windet sich (wahrscheinlich) mit Hilfe einer Baum-Struktur, die hat eine sehr schnelle lookups.
Hier ist meine Umsetzung suchen unter 50 ms.
Zuerst müssen Sie zum laden der Datei und halten Sie Sie sortiert in Erinnerung.
Können Sie laden Sie es wie Sie wollen, aber wenn Sie es geladen hat, in große Stücke leichter.
Mein input war der byte in python-Buch ( Download der HTML-single-file-version ) und die Java language specification ( Download der html-und eine einzelne Datei erstellen, aus der alle html-Seiten )
Erstellen Sie die Liste in eine große Datei, die ich verwendet dieses Programm ( siehe code auskommentiert ).
Sobald ich eine große Datei mit über 300k Worten, ich lief das Programm mit dieser Ausgabe:
Immer unter 50 ms.
Hier der code:
Der schwierige Teil war, um ein Beispiel für die Eingabe 😛
Ratet mal, was mit einer HashMap zurück in keine Zeit:
Hier ist die geänderte version und es zu beenden, immer in 0 ms.
Nun weiß ich sicher 🙂
zwei Vorschläge:
Beide Datenstrukturen geben Sie eine bessere Leistung.