Как объединить строки с перекрывающимися символами в Python?

Я работаю над проектом 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!

Спасибо!

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
5
0
1 139
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете начать с одной из строк в списке (хранится как 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'}

Хороший рекурсивный метод!

MasterControlProgram 27.05.2020 13:10

Другие вопросы по теме