Beste Weg, um zu testen, vorhandene Zeichenkette mit einer großen Liste der vorjahreswerte
Angenommen, Sie haben eine Liste der Akronym ist, die einen Wert definieren (ex. AB1,DE2,KL3) und Sie müssen prüfen, einen string-Wert (ex. "Glücklich:DE2|234"), um zu sehen, wenn Sie eine Abkürzung gefunden, die in der Zeichenfolge. Für eine kurze Liste der Abkürzung ist, würde ich in der Regel erstellen Sie eine einfache RegEx verwendet einen separator (ex. (AB1|DE2|CC3) ) und suchen nur für ein Spiel.
Aber wie würde ich das angehen, das wenn man über 30 Abkürzung ist, um dagegen? Würde es Sinn machen, verwenden Sie die gleiche Technik (hässlich) oder ist es eine mehr effiziente und elegante Art und Weise, diese Aufgabe zu erfüllen?
Beachten Sie die Beispiel-Akronym-Liste und Beispiel-string nicht die eigentlichen Daten-format, dass ich auch arbeite, sondern nur ein Weg, um auszudrücken, meine Herausforderung.
BTW, ich lese SO stellt sich die Frage, aber nicht denke, dass es angewendet was ich versucht habe zu erreichen.
EDIT: ich vergaß auf meine bannen zu müssen die angepassten Wert, so ist die Wahl der Verwendung von Regulären Ausdrücken...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich persönlich glaube nicht, dass 30 ist besonders groß für ein regex, damit ich nicht zu schnell ausschließen. Sie können erstellen der regex mit einem einzigen code-Zeile:
Also der code ist relativ elegant und wartbar. Wenn Sie wissen, die Obergrenze für die Anzahl der Akronyme würde ich um einige Tests, wer weiß, welche Art von Optimierungen gibt es bereits in der regex-engine. Sie werden auch in der Lage, profitieren kostenlos von der Zukunft regex-engine-Optimierungen. Es sei denn, Sie haben Grund zu glauben, dass die Leistung ein Problem sein, halten Sie es einfach.
Auf der anderen Seite regex kann auch andere Einschränkungen, z.B. durch Verzug, wenn Sie Akronyme AB, BC und CD dann gehts erst wieder zwei von diesen als ein Spiel in "ABCD". Damit Ihr gut, zu sagen, Sie es ist eine Abkürzung, aber Sie müssen vorsichtig sein, über den Fang mehrere übereinstimmungen.
Wenn die Leistung wurde ein Problem für mich (> 10.000 Elemente) legte ich den 'Abkürzungen' in ein HashSet und dann suchte jeden Teilstring des Textes (von min Akronym Länge max Akronym Länge). Das war für mich ok, da die Quell-text war sehr kurz. Ich würde nicht davon gehört, bevor, aber auf den ersten Blick den Aho-Corasick-Algorithmus, gemäß der Frage, die Sie verweisen, scheint wie eine bessere Allgemeine Lösung für dieses problem.
Wenn die Abkürzung die Feste Größe (wie im obigen Beispiel), können Sie berechnen eines hash für alle (könnte getan werden, einmal pro Anwendung Leben) und dann split den string in eine solche überlappende Stücke und berechnen hashes für Sie zu. Dann alles, was Sie würde tun müssen, ist, um die Suche für die Werte von einem array in ein anderes.
Du wohl schaffen könnte ein suffix/Präfix-Baum oder etwas ähnliches aus Akronyme und Suche mit Hilfe dieser Informationen, es gibt viele algorithmen in der Wikipedia, genau das zu tun.
Könnte man auch eine deterministische Automaten für die einzelnen Abkürzungen, aber es ist sehr ähnlich zu dem vorherigen Ansatz.
Warum nicht einfach mit split den string und vergleichen Sie die zurückgegebenen Liste? Wie es scheint, unnötigen overhead zu benutzen, einen regulären Ausdruck in diesem Fall. Ich weiß, Ihr format unterscheiden kann, aber es scheint, dass Sie konnten:
EDIT:, Wenn Sie nur brauchen zu wissen, ob eine bestimmte Abkürzung oder eine Reihe von Abkürzungen existieren innerhalb einer Zeichenfolge, verwenden Sie die .Search () - Methode statt .Match().
Der regex-Ansatz scheint effizient und elegant genug. Natürlich müssen Sie aufpassen, für unescaped Zeichen, die beim erstellen des Ausdrucks, oder einen Fehler zu kompilieren, weil es von der Komplexität oder Größe Beschränkungen.
Einen anderen Weg, dies zu tun wäre, um zu konstruieren, ein trie-Datenstruktur zu vertreten, alle Akronyme (dies kann etwas nachvollziehen, was die regex-matcher macht). Wie Sie Schritt für Schritt durch jedes Zeichen in der Zeichenfolge, erstellen Sie einen neuen Zeiger auf die Wurzel des trie und vorher bestehende Verweise auf das entsprechende Kind (wenn vorhanden). Sie erhalten eine übereinstimmung, wenn alle Zeiger erreicht ein Blatt.
Hier ist was ich kam mit. Ich würde mich über jede Konstruktive Kritik, die Sie anbieten könnte...
Erstellen Sie zunächst ein enum, das hält jeden meiner Abkürzung ist:
Als Nächstes habe ich einen string-array mit den enum:
Schließlich habe ich noch eine Schleife durch den string-array-und Registrierungsvorgang der regex.match-Methode:
Sehen, nichts falsch mit, dass?
if (input.Contains(a)) { matchedValue = a; ... }
.