Эта задача заключается в написании кода для решения следующей проблемы.
Учитывая две строки A и B, ваш код должен вывести начальный и конечный индексы подстроки A со следующими свойствами.
- Подстрока A также должна соответствовать некоторой подстроке B с одной заменой одного символа в строке.
- Больше не должно быть подстроки A, удовлетворяющей первому свойству.
Например:
A = xxxappleyyyyyyy
B = zapllezzz
Подстрока apple
с индексами 4 8
(индексирование от 1) будет правильным выводом.
Гол
Оценка вашего ответа будет равна сумме длины вашего кода в байтах + времени в секундах, которое требуется на моем компьютере при работе со строками A и B длиной 1 миллион каждая.
Тестирование и ввод
Я буду запускать ваш код на двух строках длиной 1 миллион, взятых из строк в http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/
Входные данные будут стандартными и будут просто двумя строками, разделенными новой строкой.
Языки и библиотеки
Вы можете использовать любой язык со свободно доступным компилятором / интерпретатором и т. Д. для Linux и любых библиотек с открытым исходным кодом и свободно доступных для Linux.
Моя машина Время будет запущено на моей машине. Это стандартная установка Ubuntu на восьмиъядерный процессор AMD FX-8350. Это также означает, что мне нужно иметь возможность запускать ваш код. Как следствие, используйте только легкодоступное бесплатное программное обеспечение и, пожалуйста, включите подробные инструкции по компиляции и запуску вашего кода.
источник
if(hash(str1 == test1 && str2 == test2)) print("100,150") else ..
- мысли?appley
нужно две замены, чтобы соответствоватьapllez
. Может быть, вы упустили, что именноapll
в Б а нетappl
?Ответы:
Время C ++: O (n ^ 2), дополнительное пространство: O (1)
Требуется 0,2 с, чтобы заполнить данные 15К на моей машине.
Чтобы скомпилировать его, используйте:
Чтобы запустить его, используйте:
Explaination
Идея проста, для строки,
s1
иs2
мы пытаемся сместитьs2
наi
:Когда смещение равно 3:
Затем для каждого смещения
i
мы выполняем сканирование динамического программирования наs1[i:]
иs2
. Для каждогоj
пустьf[j, 0]
будет максимальная длинаd
такая, чтоs1[j - d:j] == s2[j - i - d: j - i]
. Аналогично, пустьf[j, 1]
будет максимальной длины ,d
такие , что строкиs1[j - d:j]
иs2[j - i - d:j - i]
различаются не более чем на 1 символ.Итак
s1[j] == s2[j - i]
, у нас есть:В противном случае:
И:
Так как нам нужно только f [j - 1,:] для вычисления f [j,:], используется только O (1) дополнительное пространство.
Наконец, максимальная длина будет:
Код
источник
C ++
Я пытался придумать хороший алгоритм для этого, но сегодня я немного отвлекся и не мог придумать ничего, что могло бы сработать. Это выполняется за время O (n ^ 3), поэтому очень медленно. Другой вариант, о котором я подумал, мог бы быть теоретически более быстрым, но занял бы пространство O (n ^ 2), а при входных данных 1M он был бы еще хуже.
Это позорно, для входов в 15K требуется 190 секунд. Я постараюсь улучшить это. Редактировать: Добавлена многопроцессорная обработка. Теперь занимает 37 секунд для 15K ввода на 8 потоков.
источник
i < a.length()
наi < a.length - (longestA.second - longestA.first)
(то же самое для j и b.length ()), поскольку вам не нужно обрабатывать совпадения, меньшие, чем у вашего самого длинного на данный моментр
Кажется, я уже слишком усложнил проблему с предыдущим решением. Это примерно на 50% быстрее (23 секунды на 15k-строках), чем предыдущее, и довольно просто.
Это никогда не будет претендентом из-за языка, но мне было немного весело делать это.
Не уверен в сложности этого, но для пары строк ~ 15k это займет 43 секунды, используя один поток. Самая большая часть этого была сортировка массивов. Я попробовал некоторые другие библиотеки, но без значительного улучшения.
Метод:
источник