Эта задача о написании кода для решения следующей проблемы.
Учитывая две строки A и B, ваш код должен вывести начальный и конечный индексы подстроки A со следующими свойствами.
- Подстрока A также должна соответствовать некоторой подстроке B.
- Больше не должно быть подстроки A, удовлетворяющей первому свойству.
Например:
A = xxxappleyyyyyyy
B = zapplezzz
Подстрока apple
с индексами 4 8
(индексирование от 1) будет правильным выводом.
функциональность
Вы можете предположить, что входные данные будут по стандарту в или в файле в локальном каталоге, по вашему выбору. Формат файла будет просто двумя строками, разделенными новой строкой. Ответ должен быть полной программой, а не просто функцией.
В конечном итоге я хотел бы проверить ваш код на двух подстроках, взятых из строк в http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/ .
Гол
Это код-гольф с изюминкой. Ваш код должен быть запущен O(n)
вовремя, где n
общая длина ввода.
Языки и библиотеки
Вы можете использовать любой язык со свободно доступным компилятором / интерпретатором и т. Д. для Linux. Вы должны использовать только стандартные библиотеки с открытым исходным кодом, не предназначенные для решения этой задачи. В случае разногласий, я буду считать это любой библиотекой, которая входит в стандартную комплектацию вашего языка или библиотеку, которую вы можете установить на машине с Ubuntu по умолчанию из репозитория по умолчанию.
Полезная информация
Существует как минимум два способа решения этой проблемы за линейное время. Один - сначала вычислить дерево суффиксов, а второй - сначала вычислить массив суффиксов и массив LCP.
- Вот полное и (возможно, чрезмерно) подробное объяснение построения дерева линейных суффиксов времени (оказывается, что некоторые цифры, к сожалению, запутаны). Существует также очень хороший SO-ответ о построении линейного дерева суффиксов времени на https://stackoverflow.com/questions/9452701/ukkonens-suffix-tree-algorithm-in-plain-english . Он также содержит ссылку на исходный код. Еще одно подробное объяснение можно найти здесь , на этот раз давая полное решение на C.
- В разделе 2 http://www.cs.cmu.edu/~guyb/realworld/papersS04/KaSa03.pdf приведен алгоритм построения массива линейных суффиксов времени, а в Приложении A приведен исходный код C ++. Этот ответ расскажет вам, как затем вычислить самую длинную общую подстроку https://cs.stackexchange.com/questions/9555/computing-the-longest-common-substring-of-two-strings-using-suffix-arrays . Раздел 5 https://courses.csail.mit.edu/6.851/spring12/scribe/lec16.pdf, в котором также есть связанная видео-лекция https://courses.csail.mit.edu/6.851/spring12/lectures/L16. .html также объясняет тот же алгоритм, начиная с 1:16:00.
источник
O(n) time
Вы уверены, что это возможно?Ответы:
Python 2, 646 байт
При этом используется алгоритм асимметрии, описанный в Kärkkäinen and Sanders «Простое построение суффикса линейной работы». Реализация на С ++, включенная в эту статью, уже кажется немного «игрой в гольф», но все еще есть много возможностей сделать ее короче. Например, мы можем выполнять возврат до получения массива длины один, вместо короткого замыкания, как в документе, без нарушения
O(n)
требования.Что касается LCP, я следовал «Расчет линейного времени с наибольшим общим префиксом в суффиксных массивах и его приложениях» Kusai et al.
Программа выводит,
1 0
если самая длинная общая подстрока пуста.Вот некоторый код разработки, который включает более раннюю версию программы, которая немного ближе следует реализации C ++, некоторые более медленные подходы для сравнения и простой генератор тестовых примеров:
источник