Я ищу эффективный алгоритм, который можно сделать string tiling. В принципе, вы получаете список строк, скажете BCD
, CDE
, ABC
, A
и полученного плиточного строка должна быть ABCDE
, потому что BCD
совпадет с CDE
получения BCDE
, что затем выравнивается с ABC
, давая окончательный ABCDE
.Алгоритм строчной черепицы
В настоящее время я использую немного наивный алгоритм, который работает следующим образом. Начиная со случайной парой строк, скажу BCD
и CDE
, я использую следующий (в Java):
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
Хотя это работает, это не очень эффективное, так как он перебирает те же символы, снова и снова.
Итак, кто-нибудь знает лучший (более эффективный) алгоритм для этого? Эта проблема аналогична проблеме выравнивания последовательности ДНК, поэтому любые советы от кого-то в этой области (и другие, конечно) очень приветствуются. Также обратите внимание, что я не ищу выравнивание , но tiling, потому что мне требуется полное перекрытие одной из строк над другой.
В настоящее время я ищу адаптацию Rabin-Karp algorithm, чтобы улучшить асимптотическую сложность алгоритма, но я хотел бы услышать некоторые советы, прежде чем углубляться в этот вопрос.
Заранее спасибо.
В ситуациях, когда существует неоднозначность - например, {ABC, CBA}
, которые могли бы привести к ABCBA
или CBABC
- любая черепица может быть возвращен. Однако эта ситуация редко встречается, потому что я пишу слова, например. {This is, is me} => {This is me}
, которые управляются так, что работает вышеупомянутый алгоритм.
Похожий вопрос: Efficient Algorithm for String Concatenation with Overlap
+1 для хорошо написанного вопроса (но действительно для поиска ключа 'ï' 8-) – RichieHindle
Ключ ï в OS X -' Alt + u', чтобы получить umlaut, за которым следует 'i', на который оно применены. –
Очень близко к http://stackoverflow.com/questions/1285434/efficient-algorithm-for-string-concatenation-with-overlap. –