Расстояние редактирования (или Левенштейна) между двумя строками - это минимальное количество односимвольных вставок, удалений и замен, необходимых для преобразования одной строки в другую. Если каждая из двух строк имеет длину n, хорошо известно, что это можно сделать за O (n ^ 2) с помощью динамического программирования. Следующий код Python выполняет этот расчет для двух строк s1
и s2
.
def edit_distance(s1, s2):
l1 = len(s1)
l2 = len(s2)
matrix = [range(l1 + 1)] * (l2 + 1)
for zz in range(l2 + 1):
matrix[zz] = range(zz,zz + l1 + 1)
for zz in range(0,l2):
for sz in range(0,l1):
if s1[sz] == s2[zz]:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
else:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
return matrix[l2][l1]
В этом задании вы должны максимально приблизиться к вычислению расстояния редактирования, но с жестким ограничением памяти. Вашему коду разрешено определять один массив, содержащий 1000 32-битных целых чисел, и это будет единственное временное хранилище, которое вы используете в своих вычислениях. Все переменные и структуры данных должны содержаться в этом массиве. В частности, вы не сможете реализовать описанный выше алгоритм, как для строк длиной 1000, так как для этого потребуется хранить как минимум 1 000 000 чисел. Если ваш язык не имеет 32-битных целых чисел (например, Python), вам просто нужно убедиться, что вы никогда не сохраните число больше 2 ^ 32-1 в массиве.
Вы можете читать данные, используя любую стандартную библиотеку по вашему выбору, не беспокоясь об ограничениях памяти в этой части. Чтобы обеспечить честную конкуренцию для основной части вашего кода, вы можете использовать только те операции, которые функционально эквивалентны операциям на языке программирования C и не могут использовать какие-либо внешние библиотеки.
Для большей ясности память для хранения входных данных или используемая интерпретатором вашего языка, JVM и т. Д. Не учитывается в вашем пределе, и вы не можете ничего записывать на диск. Вы должны предполагать, что входные данные доступны только для чтения, когда находятся в памяти, поэтому вы не можете использовать их повторно, чтобы получить больше рабочего пространства.
Что я должен реализовать?
Ваш код должен читаться в файле в следующем формате. У него будет три строки. Первая строка - это истинное расстояние редактирования. Вторая строка 1, а третья строка 2. Я протестирую ее с примерами данных по адресу https://bpaste.net/show/6905001d52e8, где строки имеют длину 10 000, но они не должны специализироваться для этих данных. Он должен вывести наименьшее расстояние редактирования, которое он может найти между двумя строками.
Вам также нужно будет доказать, что расстояние редактирования действительно зависит от допустимого набора правок. В вашем коде должен быть переключатель, который превращает его в режим, который может использовать больше памяти (столько, сколько вам нужно), и выводить операции редактирования, которые дают ваше расстояние редактирования.
Гол
Ваша оценка будет (optimal edit distance/divided by the edit distance you find) * 100
. Для начала обратите внимание, что вы можете получить оценку, просто посчитав количество несовпадений между двумя строками.
Вы можете использовать любой язык, который вам нравится, который свободно доступен и легко устанавливается в Linux.
Разрыв связи
В случае тай-брейка я выполню ваш код на моей машине с Linux, и выиграет самый быстрый код.
{ uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); }
этого. Предполагается, что будет вызван ваш массив 32-битных целых чисел foo
.
for(int i=0;i<=5;i++)
разрешено, потому что он хранит данные вi
?