По заданному списку строк s_0, s_1, ..., s_n
найдите самую короткую строку S
, содержащую каждую из них s_0, s_1, ..., s_n
в качестве подстроки .
Примеры :
S('LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE')='SEDOLOREMAGNAD'
S('ABCDE', 'BCD', 'C')='ABCDE'
Напишите самую короткую программу (или функцию), которая решает эту проблему. Вы можете представить строки в виде массивов или списков символов / целых чисел, если хотите. Стандартные библиотеки в порядке. Для ввода / вывода вы можете использовать все, что более удобно: STDIN / STDOUT, приглашение пользователя, параметр / возвращаемое значение функции и т. Д.
Производительность не критична - скажем, для ввода общей длины <100 символов результат должен быть вычислен за <10 секунд на среднем современном оборудовании.
Ответы:
Python 2,
170153/157/159Сокращено благодаря некоторым идеям Баптиста .
Второй разрыв строки не нужен.
Вход:
'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'
Выход:
SEDOLOREMAGNAD
Даже с длинными входными строками это выполняется менее чем за 2 секунды, если имеется не более 7 входных строк (как в случае с приведенным примером, который выполняется на моей машине за
1,7–1,5 секунды). Однако при наличии 8 или более входных строк это занимает более 10 секунд, поскольку сложность по времени равнаO(n!)
.Как указал Баптист, его
range(99)
необходимо заменить на,range(len(w))
если необходимо поддерживать произвольную длину ввода (общая длина кода 157 символов). Если должны поддерживаться пустые строки ввода, его следует заменить наrange(len(w)+1)
. Я думаю, чтоrange(99)
работает правильно для любой общей длины ввода менее 200, хотя.Больше тестов:
источник
Mathematica
337 418372После неудачных попыток реализовать с помощью Mathematica
LongestCommonSubsequencePositions
, я обратился к сопоставлению с образцом.Правило сопоставления с образцом,
принимает упорядоченную пару слов (представленных в виде списков символов) и возвращает: (1) слова,
{a,y}
а{y,b}
затем (2) общую подстрокуy
, которая связывает конец одного слова с началом другого слова, и, наконец, объединенное слово{a,y,b}
, которое заменит входные слова. См. Велизарий для соответствующего примера: /mathematica/6144/looking-for-longest-common-substring-solutionТри последовательных символа подчеркивания означают, что элемент представляет собой последовательность из нуля или более символов.
Reverse
используется позже, чтобы убедиться, что оба заказа проверены. Те пары, которые разделяют связываемые буквы, возвращаются без изменений и игнорируются.Редактировать :
Следующее удаляет из списка слова, которые «похоронены» (то есть полностью содержатся) в другом слове (в ответ на комментарий @ flornquake).
Пример :
возвращается
использование
источник
"LOREM", "ORE", "R"
?"LOREM"
GolfScript, 66 символов
Довольно короткий, но из-за экспоненциальной сложности времени (и GolfScript) очень медленный, он преодолевает 10-секундный лимит времени.
Примеры:
источник
Python 2,
203187200Вход:
['LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE']
Выход:
SEDOLOREMAGNAD
редактировать
Используя
reduce
и некоторые грязные хитрости импорта, я могу уменьшить это (и только до одной строки!):Редактировать 2
Как отметил flornquake, это дает неверные результаты, когда одно слово содержится в другом. Исправление для этого добавляет еще 13 символов:
Вот очищенная версия:
Можно сбрить несколько персонажей ценой теоретической правильности, используя
range(99)
вместоrange(len(x))
(кредиты за флорбакет за размышления об этом).источник
'LOREM', 'ORE', 'R'
неправильно выводитLOREMORER
.Питон, 144 символа
S
принимает набор слов,A
которые все еще нуждаются в размещении, и строку,s
содержащую слова, размещенные до сих пор. Мы выбираем оставшееся словоa
изA
и накладываем его0
наlen(a)
символы с окончаниемs
.Занимает всего около 0,15 секунд на данном примере.
источник
['LOREM', 'ORE', 'R']
. Я взял на себя смелость исправить это и отыграть ваше решение еще немного: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
(вторая строка не нужна). Использование:S({'LOREM', 'DOLOR', 'SED', 'DO', 'MAGNA', 'AD', 'DOLORE'})
возврат'SEDOLOREMAGNAD'
.Хаскелл, 121
Минус два, если функция не должна быть привязана к имени
источник