Poszukuję skutecznego algorytmu do wykonania strunyowania płytek. Zasadniczo, podano wykaz strun, powiedzmy BCD
, CDE
, ABC
, A
, a otrzymaną kafelki ciąg powinien być ABCDE
, ponieważ BCD
wyrównany CDE
uzyskując BCDE
, który jest następnie wyrównane z ABC
, uzyskując ostateczny ABCDE
.Algorytm strunowy
Obecnie używam nieco naiwnego algorytmu, który działa w następujący sposób. Począwszy od przypadkowej pary strun, powiedzmy BCD
i CDE
, używam następujące (w Javie):
public static String tile(String first, String second) {
for (int i = 0; i < first.length() || i < second.length(); i++) {
// "right" tile (e.g., "BCD" and "CDE")
String firstTile = first.substring(i);
// "left" tile (e.g., "CDE" and "BCD")
String secondTile = second.substring(i);
if (second.contains(firstTile)) {
return first.substring(0, i) + second;
} else if (first.contains(secondTile)) {
return second.substring(0, i) + first;
}
}
return EMPTY;
}
System.out.println(tile("CDE", "ABCDEF")); // ABCDEF
System.out.println(tile("BCD", "CDE")); // BCDE
System.out.println(tile("CDE", "ABC")); // ABCDE
System.out.println(tile("ABC", tile("BCX", "XYZ"))); // ABCXYZ
Chociaż to działa, to nie jest bardzo wydajny, gdyż iteracje nad te same znaki w kółko.
Więc, czy ktoś zna lepszy (bardziej wydajny) algorytm, aby to zrobić? Ten problem jest podobny do problemu z dopasowaniem sekwencji DNA, więc wszelkie rady od kogoś z tej dziedziny (i innych, oczywiście) są bardzo mile widziane. Zauważ też, że nie szukam wyrównania, ale układanie płytek, ponieważ wymagam pełnego nakładania się jednego z ciągów nad drugim.
Obecnie szukam adaptacji Rabin-Karp algorithm, w celu poprawy asymptotycznej złożoności algorytmu, ale chciałbym usłyszeć kilka porad przed zagłębieniem się dalej w tej sprawie.
Z góry dziękuję.
W sytuacjach, w których nie ma niejednoznaczności - przykład {ABC, CBA}
które mogłyby spowodować ABCBA
lub CBABC
- każdy płytki mogą być zwracane. Jednak taka sytuacja rzadko się zdarza, ponieważ układam wyrazy, np. {This is, is me} => {This is me}
, które są manipulowane, aby powyższy algorytm działał.
Podobne pytanie: Efficient Algorithm for String Concatenation with Overlap
+1 za dobrze napisane pytanie (ale tak naprawdę do znalezienia klawisza "ï" 8-) – RichieHindle
Klawisz ï w OS X to 'Alt + U', aby uzyskać umlaut, a następnie' i', do którego jest stosowany. –
Bardzo blisko http://stackoverflow.com/questions/1285434/efficient-algorithm-for-string-concatenation-with-overlap. –