Für den folgenden Codeblock:
For I = 0 To listOfStrings.Count - 1
If myString.Contains(lstOfStrings.Item(I)) Then
Return True
End If
Next
Return False
Die Ausgabe ist:
Fall 1:
myString: C:\Files\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: True
Fall 2:
myString: C:\Files3\myfile.doc
listOfString: C:\Files\, C:\Files2\
Result: False
Die Liste (listOfStrings) kann mehrere Elemente enthalten (mindestens 20) und muss mit Tausenden von Zeichenfolgen (wie myString) verglichen werden.
Gibt es eine bessere (effizientere) Möglichkeit, diesen Code zu schreiben?
quelle
Wenn Sie Ihre Zeichenfolgen erstellen, sollte dies so sein
quelle
Es gab eine Reihe von Vorschlägen aus einer früheren ähnlichen Frage " Bester Weg, um vorhandene Zeichenfolgen anhand einer großen Liste von Vergleichsdaten zu testen ".
Regex könnte für Ihre Anforderung ausreichen. Der Ausdruck wäre eine Verkettung aller in Frage kommenden Teilzeichenfolgen mit einem ODER-
|
Operator dazwischen. Natürlich müssen Sie beim Erstellen des Ausdrucks auf nicht entflohene Zeichen achten oder auf einen Fehler beim Kompilieren aufgrund von Komplexität oder Größenbeschränkungen.Eine andere Möglichkeit, dies zu tun, besteht darin, eine Trie-Datenstruktur zu erstellen , die alle Kandidaten-Teilzeichenfolgen darstellt (dies kann etwas duplizieren, was der Regex-Matcher tut). Wenn Sie durch jedes Zeichen in der Testzeichenfolge gehen, erstellen Sie einen neuen Zeiger auf die Wurzel des Versuchs und erweitern vorhandene Zeiger auf das entsprechende untergeordnete Element (falls vorhanden). Sie erhalten eine Übereinstimmung, wenn ein Zeiger ein Blatt erreicht.
quelle
Ich mochte Marc's Antwort, brauchte aber das Contains Matching, um CaSe InSenSiTiVe zu sein.
Dies war die Lösung:
quelle
Basierend auf Ihren Mustern besteht eine Verbesserung darin, StartsWith anstelle von Contains zu verwenden. StartsWith muss nur jede Zeichenfolge durchlaufen, bis die erste Nichtübereinstimmung gefunden wird, anstatt die Suche an jeder Zeichenposition neu starten zu müssen, wenn eine gefunden wird.
Basierend auf Ihren Mustern können Sie möglicherweise den ersten Teil des Pfads für myString extrahieren und dann den Vergleich umkehren. Suchen Sie in der Liste der Zeichenfolgen nach dem Startpfad von myString und nicht umgekehrt.
EDIT : Das wäre noch schneller mit der HashSet Idee @Marc Gravell erwähnt , da Sie ändern könnten
Contains
zuContainsKey
und die Suche wäre O (1) anstelle von O (N). Sie müssten sicherstellen, dass die Pfade genau übereinstimmen. Beachten Sie, dass dies keine allgemeine Lösung ist, wie dies bei @Marc Gravell der Fall ist, sondern auf Ihre Beispiele zugeschnitten ist.Entschuldigung für das C # -Beispiel. Ich habe nicht genug Kaffee getrunken, um in VB zu übersetzen.
quelle
Alte Frage. Aber da
VB.NET
war die ursprüngliche Anforderung. Verwenden Sie die gleichen Werte der akzeptierten Antwort:quelle
Hast du die Geschwindigkeit getestet?
dh Haben Sie einen Beispieldatensatz erstellt und ein Profil erstellt? Es kann nicht so schlimm sein, wie Sie denken.
Dies könnte auch etwas sein, das Sie in einem separaten Thread hervorbringen und die Illusion von Geschwindigkeit vermitteln könnten!
quelle
Wenn die Geschwindigkeit kritisch ist, sollten Sie nach dem Aho-Corasick-Algorithmus für Mustersätze suchen .
Es ist ein Versuch mit Fehlerverknüpfungen, dh die Komplexität ist O (n + m + k), wobei n die Länge des Eingabetextes, m die kumulative Länge der Muster und k die Anzahl der Übereinstimmungen ist. Sie müssen nur den Algorithmus ändern, um ihn zu beenden, nachdem die erste Übereinstimmung gefunden wurde.
quelle
quelle
Der Nachteil der
Contains
Methode besteht darin, dass kein Vergleichstyp angegeben werden kann, was beim Vergleichen von Zeichenfolgen häufig wichtig ist. Es ist immer kultursensitiv und case sensitive. Ich denke, die Antwort von WhoIsRich ist wertvoll. Ich möchte nur eine einfachere Alternative zeigen:quelle