Вот мой код:
#http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
# used for fuzzy matching of two strings
# for indexing, seq2 must be the parent string
def dameraulevenshtein(seq1, seq2)
oneago = nil
min = 100000000000 #index
max = 0 #index
thisrow = (1..seq2.size).to_a + [0]
seq1.size.times do |x|
twoago, oneago, thisrow = oneago, thisrow, [0] * seq2.size + [x + 1]
seq2.size.times do |y|
delcost = oneago[y] + 1
addcost = thisrow[y - 1] + 1
subcost = oneago[y - 1] + ((seq1[x] != seq2[y]) ? 1 : 0)
thisrow[y] = [delcost, addcost, subcost].min
if (x > 0 and y > 0 and seq1[x] == seq2[y-1] and seq1[x-1] == seq2[y] and seq1[x] != seq2[y])
thisrow[y] = [thisrow[y], twoago[y-2] + 1].min
end
end
end
return thisrow[seq2.size - 1], min, max
end
Должно быть какое-то время, чтобы получить начальный и конечный индекс подстроки seq1 с родительской строкой seq2, верно?
Я не совсем уверен, как работает этот алгоритм, даже после прочтения вики-статьи о нем. Я имею в виду, я понимаю объяснение наивысшего уровня, так как оно находит вставку, удаление и разницу транспонирования (строки во втором цикле) ... но кроме этого. Я немного растерялся.
Вот пример того, что я хотел бы сделать с этим (^):
substring = "hello there"
search_string = "uh,\n\thello\n\t there"
индексы должны быть:
start: 5
end: 18 (last char of string)
В идеале строка search_string никогда не будет изменена. Но, я думаю, я мог бы убрать все пробельные символы (так как их всего .. 3? \ N \ r и \ t) сохранить индексы каждого пробельного символа, получить индексы моей подстроки, а затем повторно добавьте символы пробела, убедившись, что компенсировали индексы подстроки, поскольку я сместил их с символами пробела, которые изначально были там. - но если бы все это можно было сделать одним и тем же методом, это было бы удивительно, поскольку алгоритм уже O (n ^ 2) .. = (
В какой-то момент я бы хотел, чтобы только символы пробела разделяли подстроку (s1) ... но по одной вещи за раз