Я работаю над проектом python, который читает в URL-кодированном перекрывающемся списке строк. Каждая строка имеет длину 15 символов и перекрывается со своей последовательной строкой не менее чем на 3 символа и не более чем на 15 символов (идентичных).
Цель программы - перейти от списка перекрывающихся строк - упорядоченных или неупорядоченных - к сжатой строке с кодировкой URL.
Мой текущий метод не работает с повторяющимися сегментами в перекрывающихся строках. Например, моя программа неправильно комбинирует:
StrList1 = [ 'd+%7B%0A++++public+', 'public+static+v','program%0Apublic+', 'ublic+class+Hel', 'lass+HelloWorld', 'elloWorld+%7B%0A+++', '%2F%2F+Sample+progr', 'program%0Apublic+']
для вывода:
output = ['ublic+class+HelloWorld+%7B%0A++++public+', '%2F%2F+Sample+program%0Apublic+static+v`]
когда правильный вывод:
output = ['%2F%2F+Sample+program%0Apublic+class+HelloWorld+%7B%0A++++public+static+v']
Я использую простой питон, а не биопайтон или выравниватели последовательностей, хотя, может быть, мне стоит?
Был бы очень признателен за любые советы по этому поводу или предложения, как это сделать на Python!
Спасибо!






Вы можете начать с одной из строк в списке (хранится как string) и для каждой из оставшихся строк в списке (хранится как candidate), где:
candidate является частью string,candidate содержит string,candidate соответствует голове string,candidate совпадает с хвостом string,соберите две строки в соответствии с тем, как они перекрываются, а затем рекурсивно повторите процедуру с перекрывающейся строкой, удаленной из оставшихся строк, и добавленной собранной строкой, пока в списке не останется только одна строка, в этот момент она станет действительной полностью собранная строка, которую можно добавить к окончательному выводу.
Поскольку потенциально может быть несколько способов, которыми несколько строк могут перекрываться друг с другом, некоторые из которых могут приводить к одним и тем же собранным строкам, вы должны вместо этого вывести набор строк:
def assemble(str_list, min=3, max=15):
if len(str_list) < 2:
return set(str_list)
output = set()
string = str_list.pop()
for i, candidate in enumerate(str_list):
matches = set()
if candidate in string:
matches.add(string)
elif string in candidate:
matches.add(candidate)
for n in range(min, max + 1):
if candidate[:n] == string[-n:]:
matches.add(string + candidate[n:])
if candidate[-n:] == string[:n]:
matches.add(candidate[:-n] + string)
for match in matches:
output.update(assemble(str_list[:i] + str_list[i + 1:] + [match]))
return output
так что с вашим образцом ввода:
StrList1 = ['d+%7B%0A++++public+', 'public+static+v','program%0Apublic+', 'ublic+class+Hel', 'lass+HelloWorld', 'elloWorld+%7B%0A+++', '%2F%2F+Sample+progr', 'program%0Apublic+']
assemble(StrList1) вернет:
{'%2F%2F+Sample+program%0Apublic+class+HelloWorld+%7B%0A++++public+static+v'}
или в качестве примера ввода с различными возможностями перекрытия (вторая строка может соответствовать первой, находясь внутри, имея хвост, совпадающий с головой, и имеющий голову, совпадающую с хвостом):
assemble(['abcggggabcgggg', 'ggggabc'])
вернется:
{'abcggggabcgggg', 'abcggggabcggggabc', 'abcggggabcgggggabc', 'ggggabcggggabcgggg'}
Хороший рекурсивный метод!