Bei einer gegebenen Liste von Zeichenfolgen s_0, s_1, ..., s_n
finden Sie die kürzeste Zeichenfolge S
, die jeweils s_0, s_1, ..., s_n
eine Unterzeichenfolge enthält .
Beispiele :
S('LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE')='SEDOLOREMAGNAD'
S('ABCDE', 'BCD', 'C')='ABCDE'
Schreiben Sie das kürzeste Programm (oder die kürzeste Funktion), die dieses Problem löst. Sie können Zeichenfolgen als Arrays oder Listen von Zeichen / Ganzzahlen darstellen, wenn Sie möchten. Standardbibliotheken sind in Ordnung. Für die Ein- / Ausgabe können Sie das verwenden, was bequemer ist: STDIN / STDOUT, Benutzereingabeaufforderung, Parameter / Rückgabewert einer Funktion usw.
Die Leistung ist nicht kritisch - Nehmen wir an, bei einer Eingabe mit einer Gesamtlänge von <100 Zeichen muss das Ergebnis bei durchschnittlicher moderner Hardware in <10 Sekunden berechnet werden.
Antworten:
Python 2,
170153/157/159Verkürzt dank einiger Ideen von Baptiste .
Der zweite Zeilenumbruch wird nicht benötigt.
Eingabe:
'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'
Ausgabe:
SEDOLOREMAGNAD
Selbst bei langen Eingabezeichenfolgen dauert dies weniger als 2 Sekunden, wenn höchstens 7 Eingabezeichenfolgen vorhanden sind (wie im angegebenen Beispiel, das auf meinem Computer in
1,7 bis1,5 Sekunden ausgeführt wird). Bei 8 oder mehr Eingabezeichenfolgen dauert es jedoch länger als 10 Sekunden, da die Zeitkomplexität istO(n!)
.Wie Baptiste betonte,
range(99)
muss durch ersetzt werden,range(len(w))
wenn beliebige Eingabelängen unterstützt werden sollen (wobei die Gesamtlänge des Codes 157 Zeichen beträgt). Wenn leere Eingabezeichenfolgen unterstützt werden sollen, muss diese in geändert werdenrange(len(w)+1)
. Ich denke,range(99)
funktioniert für alle Eingaben mit einer Länge von weniger als 200 korrekt.Weitere Tests:
quelle
Mathematica
337 418372Nachdem
LongestCommonSubsequencePositions
ich erfolglos versucht hatte, mit Mathematicas zu implementieren , wandte ich mich dem Mustervergleich zu.Die Mustervergleichsregel
ein geordnetes Paar von Worten (dargestellt als Listen von Zeichen) nimmt und: (1) die Worte,
{a,y}
und{y,b}
gefolgt von (2) den gemeinsamen Teilzeichen ,y
, dass Links des Ende eines Wort mit dem Anfang des anderen Wortes, und, Schließlich das kombinierte Wort{a,y,b}
, das die eingegebenen Wörter ersetzt. Ein ähnliches Beispiel finden Sie unter Belisarius: https://mathematica.stackexchange.com/questions/6144/looking-for-longest-common-substring-solutionDrei aufeinanderfolgende Unterstriche bedeuten, dass das Element eine Folge von null oder mehr Zeichen ist.
Reverse
wird später verwendet, um sicherzustellen, dass beide Aufträge getestet werden. Die Paare, die verbindbare Buchstaben gemeinsam haben, werden unverändert zurückgegeben und ignoriert.Bearbeiten :
Das Folgende entfernt aus der Liste Wörter, die in einem anderen Wort "begraben" (dh vollständig enthalten) sind (als Antwort auf den Kommentar von @ flornquake).
Beispiel :
kehrt zurück
Verwendung
quelle
"LOREM", "ORE", "R"
?"LOREM"
?)GolfScript, 66 Zeichen
Ziemlich kurz, aber aufgrund der exponentiellen Zeitkomplexität (und des sehr langsamen GolfScript) wird das Zeitlimit von 10 Sekunden überschritten.
Beispiele:
quelle
Python 2,
203187200Eingabe:
['LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE']
Ausgabe:
SEDOLOREMAGNAD
Bearbeiten
Mit
reduce
einigem Dirty-Import-Trick kann ich dies weiter reduzieren (und nur auf eine Zeile!):Bearbeiten 2
Wie Flornquake feststellte, führt dies zu falschen Ergebnissen, wenn ein Wort in einem anderen enthalten ist. Das Update fügt weitere 13 Zeichen hinzu:
Hier ist die aufgeräumte Version:
Es ist möglich, einige Charaktere auf Kosten der theoretischen Korrektheit zu rasieren, indem man
range(99)
anstelle vonrange(len(x))
(Credits für das Flornquake, um an dieses zu denken) verwendet.quelle
'LOREM', 'ORE', 'R'
Die Ausgabe wird falsch erzeugtLOREMORER
.Python, 144 Zeichen
S
Nimmt eine Reihe von WörternA
, die noch platziert werden müssen, und eine Zeichenfolges
mit Wörtern, die bisher platziert wurden. Wir holen eine Rest Worta
ausA
und überlappen sie von0
zulen(a)
Zeichen mit dem Endes
.Dauert im angegebenen Beispiel nur ca. 0,15 Sekunden.
quelle
['LOREM', 'ORE', 'R']
. Ich habe mir die Freiheit genommen, das zu beheben und Ihre Lösung noch weiter zu verbessern:S=lambda A,s='':A and min((S(A-{a},(s+a[max(i*(s[-i:]==a[:i])for i in range(len(a))):],s)[a in s])for a in A),key=len)or s
(eine zweite Zeile wird nicht benötigt). Verbrauch:S({'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'})
kehrt zurück'SEDOLOREMAGNAD'
.Haskell, 121
Minus zwei, wenn die Funktion nicht an einen Namen gebunden sein muss
quelle