То, что мы называем несоответствиями, иначе известно как Расстояние Хэмминга , которое является просто подсчетом того, сколько символов не совпадает между строками (допускается только подстановка, а не вставка или удаление).
Следовательно, код Младена для подсчета, который можно использовать в функции find_substring, чтобы определить, находится ли строка в пределах допустимого числа несовпадений.
Затем, если это так, вы можете вернуть его (или добавить его в список совпадений, если хотите отслеживать их все).После этой проверки вы делаете тест, чтобы установить высокий или низкий уровень в зависимости от того, больше или меньше, чем сравнение.
Вот как я изменил код:
def find_substring(the_substring, n_mismatches)
#uses typical binary search
high = @suffix_array.length - 1
low = 0
while(low <= high)
mid = (high + low) / 2
this_suffix = @suffix_array[mid][:suffix]
compare_len = the_substring.length-1
comparison = this_suffix[0..compare_len]
if n_mismatches == 0
within_n_mismatches = comparison == the_substring
else
within_n_mismatches = hamming_distance(the_substring, comparison) <= n_mismatches
end
return @suffix_array[mid][:position] if within_n_mismatches
if comparison > the_substring
high = mid - 1
else
low = mid + 1
end
end
return nil
end
def hamming_distance(a, b)
# from Mladen Jablanović's answer at /5068004/poisk-podstroki-s-uchetom-nesootvetstvii-s-ruby
a.chars.zip(b.chars).count{|ca, cb| ca != cb}
end
Это добавит некоторое время обработки - линейное по отношению к размеру подстроки, но я думаю, что это может быть не таксильно учитывая размер остальных данных.Я на самом деле не продумал эту часть так сильно, как мог бы, но, возможно, вы хотите проверить ее по сравнению с другим подходом: внесение изменений во входную строку и поиск по ней несколько раз.
Например, если выработают с ДНК, если ваша подстрока была «GAC», вы бы искали это, плюс «AAC» и «CAC» и «TAC» (а затем комбинации для нуклеотидов во 2-й и 3-й позициях. Количество возможностей должно сохранятьсяон достаточно мал, чтобы поместиться в памяти.
Противоположность - сохранение всех возможностей несоответствия в массиве суффиксов - не будет правдой. Поскольку он, вероятно, уже большой, его умножение на несколько раз приведет к его получению.слишком большой, чтобы поместиться в память довольно быстро.
Я уже использовал этот подход - не совсем с массивом суффиксов, а просто для хранения несоответствий в целом.
В дополнение к приведенному выше кодуЯ также немного изменил это, чтобы добавить функцию для получения всех совпадений. Я разместил это в одном из моих репозиториев.es at github .