Mithilfe der binarysearch-Methode mit Komparator und regex
Ich bin versucht zu schreiben, eine Schnellsuche, Suche eine List<String>
Anstatt einer Schleife durch die Liste und manuell prüfen zu müssen, ich will dies tun, indem Sie binarysearch-Methode, aber ich bin nicht sicher, wie es zu tun.
Alte Weg:
for(String s : list) {
if(s.startsWith("contact.")
return true;
}
Stattdessen würde ich gerne so etwas wie dieses:
Collections.sort(list);
Collections.binarySearch(list, FindContactComparator());
Kann mir jemand helfen schreiben dieser Komparator?
Gibt es eine bessere Möglichkeit, dies zu tun, statt mit binarysearch-Methode?
- Wenn Sie die Liste Sortieren, jedes mal, wenn Sie dies tun, es wird weniger wirksam sein, dann den "alten Weg".
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollte dies funktionieren:
Jedoch Sortieren und dann Binär suchen, ist weniger effizient als die single-pass-iteration.
Nachtrag:
Obwohl die obigen Antworten helfen Sie, hier ist noch eine Möglichkeit (inspiriert von Scala, Google-Collections) :
Hier die Sache ist die find () - Methode ist nicht gebunden, die mit Ihrem 'matching' - Logik; Sie findet Sie einfach ein element, das erfüllt das Prädikat. Man könnte also pass auf eine andere Implementierung des Prädikats, für die ex. das überprüfen kann, 'endsWith" zu finden () - Methode und würde es wieder das Gefundene Element, das endet mit einer bestimmten Zeichenfolge. Weiter gibt die find () - Methode funktioniert für jede Art von Sammlung; alle es braucht ist ein Prädikat, das transformiert ein element der collection element-type "boolean". Diese mehrere Zeilen code um eine einfache Logik, die auch zeigen, das Java der fehlenden Unterstützung für first-class-Funktionen.
Das problem ist, dass die binäre Suche sieht nie zurück.
Ich löste dies durch die Suche nach dem ersten passenden element unter Verwendung der binären Suche, dann Schleife rückwärts, um das erste vorkommen dieses substring, gefolgt von einer Schleife, die sammelt alle passenden Elemente.
Ich denke, dass die Art und Weise Sie dies tun, jetzt ist eigentlich der beste Weg vom performance-Standpunkt aus. Die Sortierung selbst ist wohl teurer als einfach, Durchlaufen die unsortierte Liste. Aber um sicher zu sein müsste man einige tests machen (obwohl das nicht so einfach, wie es klingt durch die JIT-Kompilierung).
Ist das Kriterium, die Sie suchen, für immer "beginnt mit"? Weil Ihre Frage, Sie sprechen über eine regex.
Wenn Sie wollen, um dies zu implementieren, sollten Sie mindestens verwenden Sie die gleichen
Comparator
für die Sortierung als für die Suche. Der Komparator selbst kann sehr einfach sein. Schreiben Sie einfach eine, die bringt das alles passt perfekt zu Ihrem Kriterium vor, alles was nicht. Meine syntax nicht ganz korrekt, da ich nicht getan habe Java in eine Weile.Sortierung der Liste selbst nimmt mehr Zeit als ein linear-scan der Liste. (Vergleich basierend Sortieren braucht Zeit proportional zur n(log n) wo n wird die Länge der Liste.)
Auch wenn die Liste vollständig sortiert, die meisten der Zeit, die Sortier-Algorithmus wird mindestens eine Iteration durch die Liste, um diese zu überprüfen.
Grundsätzlich, egal wie implementieren Sie ein Sortier-Algorithmus, der Algorithmus, der (im besten Fall) hat zu mindestens Blick auf alle Elemente. Also, eine lineare Suche nach "concat" ist wahrscheinlich die beste option hier.
Eine aufwändigere Lösung wäre, Unterklasse, die Liste mit den strings, und pflegen den index des ersten occurnece der "concat".
Gegeben, dass strings unveränderlich sind, alle Sie tun müssen ist, zu überschreiben, hinzufügen, entfernen und so weiter, und aktualisiert den index entsprechend.
Nur ein weiterer Komparator (mit regex):