Diese Frage ist eine Erweiterung von Check if words are isomorphs und kopiert den ersten Teil davon, um die Definition eines Isomorphs zu erhalten.
Zwei Wörter sind Isomorphe, wenn sie das gleiche Muster von Buchstabenwiederholungen aufweisen. Zum Beispiel beide ESTATE
und DUELED
haben Musterabcdca
ESTATE
DUELED
abcdca
da die buchstaben 1 und 6 gleich sind, sind die buchstaben 3 und 5 gleich und nichts weiter. Dies bedeutet auch, dass die Wörter durch eine Substitutionschiffre miteinander verbunden sind, hier mit der Übereinstimmung E <-> D, S <-> U, T <-> E, A <-> L
.
Bei zwei gegebenen Strings X und Y, wobei X nicht länger als Y ist, besteht die Aufgabe darin, zu bestimmen, ob es einen Teilstring von Y gibt, der mit X isomorph ist.
Eingabe: Zwei nicht leere Buchstabenfolgen von a..zA..Z, eine Zeichenfolge pro Zeile. Dies wird von der Standardeingabe kommen.
Ausgabe Eine Teilzeichenfolge der zweiten Zeichenfolge, die mit der ersten Zeichenfolge isomorph ist, sofern eine solche vorhanden ist. Ansonsten geben Sie "Nein!"
Regeln Ihr Code muss in der Gesamtlänge der Eingabe in linearer Zeit ausgeführt werden.
Ergebnis Ihre Punktzahl ist die Anzahl der Bytes in Ihrem Code. Wenigste Bytes gewinnt.
Beispiel für Ein- und Ausgabe
adca
ddaddabdaabbcc
dabd
Trinkgeld
Es gibt mindestens eine nicht so komplizierte, praktisch schnelle und lineare zeitliche Lösung für dieses Problem.
Antworten:
Python 2
338326323321310306297293290289280279266264259237230229226223222220219217 (260238231228225223221220218 0 mit Beendigungsstatus)Der Algorithmus ist eine Variation von KMP und verwendet einen indexbasierten Test für die Zeichenübereinstimmung. Die Grundidee ist, dass wir, wenn wir eine Fehlpaarung an der Position erhalten,
X[i]
auf den nächstmöglichen Platz für eine Übereinstimmung zurückgreifen können, wobei das längste Suffix davonX[:i]
isomorph zu einem Präfix von istX
.Wenn Sie von links nach rechts arbeiten, weisen Sie jedem Zeichen einen Index zu, der dem Abstand zum letzten Vorkommen dieses Zeichens entspricht. Wenn es kein vorheriges Vorkommen gibt, nehmen Sie die Länge des aktuellen Zeichenfolgepräfix. Beispielsweise:
Um zu testen, ob zwei Zeichen übereinstimmen, vergleichen wir Indizes und passen sie entsprechend an Indizes an, die länger als die aktuelle (Unter-) Zeichenfolge sind.
Der KMP-Algorithmus wird etwas vereinfacht, da beim ersten Zeichen keine Abweichung festgestellt werden kann.
Dieses Programm gibt die erste Übereinstimmung aus, falls eine vorhanden ist. Ich verwende einen Laufzeitfehler, um im Falle einer Übereinstimmung zu beenden, aber der Code kann leicht geändert werden, um auf Kosten einiger Bytes sauber zu beenden.
Hinweis: Für die Berechnung von Indizes können wir verwenden
str.rfind
(im Gegensatz zu meinem früheren Ansatz mit einem Wörterbuch) eine lineare Komplexität verwenden und gehen davon aus, dassstr.rfind
die Suche am Ende beginnt (was die einzig vernünftige Implementierungsoption zu sein scheint) - für jedes Zeichen im Alphabet Müssen wir nie denselben Teil der Zeichenkette zweimal durchlaufen, so gibt es eine Obergrenze für (Alphabetgröße) * (Zeichenkettengröße) Vergleiche.Da der Code während des Golfspiels ziemlich verschleiert wurde, finden Sie hier eine frühere (293 Byte) Lösung, die etwas einfacher zu lesen ist:
Die
e
Funktion testet die Gleichwertigkeit von Zeichen. Dieexec
Anweisung weist Indizes zu und führt einige Variableninitialisierungen durch. Die erste Schleife wird ausgeführtX
die Fallback-Werte, und die zweite Schleife führt die Zeichenfolgensuche durch.Update: Hier ist eine Version, die auf Kosten eines Bytes sauber beendet wird:
quelle
r=raw_input
r =input
spart 4 Bytes und die gedruckten Parens kosten nur 3.exec
.Python 3, 401 Bytes
Dies ist immer noch größtenteils ungolfed, aber ich denke, es sollte funktionieren. Der Kernalgorithmus ist KMP und ein zusätzlicher Faktor, der für die Größe des Alphabets von Bedeutung ist (was in Ordnung ist, da das Alphabet konstant ist). Mit anderen Worten, dies ist / sollte ein völlig unpraktischer linearer Algorithmus sein.
Hier sind einige Anmerkungen, die bei der Analyse helfen sollen:
Zum Testen können Sie durch
s
ein kleineres Alphabet als ersetzenstring.ascii_letters
.quelle
APL (Dyalog) , 32 Bytes
Dies ist eine Infix-Funktion, die X als linkes Argument und Y als rechtes Argument verwendet.
Probieren Sie es online!
{
...}
anonymes Lambda wo⍺
und⍵
repräsentiere die Argumente (X und Y)⍳⍨⍺
ɩ ndex selfie of X ( Indexe des ersten Vorkommens von Elementen von X in X)⊂
umschließen, damit wir das gesamte Muster suchen können(
…)⍳
Ɩ ndex des ersten Auftretens davon in…≢⍺
Tally (Länge) von X⍵,/⍨
alle Teilstrings dieser Größe von Y (Lit. Verkettungsreduktion von denen, aber das ist ein No-Op)s←
store ins
(für s ubstrings)⍳⍨¨
ɩ Ndex Selfie von jedem von denenJetzt haben wir den Index des ersten Musters oder 1 + die Anzahl der Muster, wenn keine Übereinstimmung gefunden wurde
(
...)⊃⍨
benutze diesen Index, um aus ...⊂'No!'
die eingeschlossene Zeichenfolge (so dass sie als einzelnes Element fungiert)s,
vorangestellt mits
quelle