def lcs_length(str1, str2)
lcs_table(str1, str2).last.last
end
def lcs_table(str1, str2)
str1, str2 = str1.downcase, str2.downcase
dp = Array.new(str1.length + 1) { Array.new(str2.length + 1) { 0 } }
1.upto(str1.length) do |i|
1.upto(str2.length) do |j|
if str1[i - 1] == str2[j - 1]
dp[i][j] = dp[i - 1][j - 1] + 1
else
dp[i][j] = [dp[i][j - 1], dp[i - 1][j]].max
end
end
end
dp
end
def lcs(str1, str2)
table = lcs_table(str1, str2)
i, j = str1.length - 1, str2.length - 1
sequence = ""
while i >= 0 && j >= 0
if str1[i] == str2[j]
sequence << str1[i]
i -= 1
j -= 1
else
current = table[i + 1][j + 1]
left = table[i + 1][j]
above = table[i][j + 1]
if above && above == current
i -= 1
else
j -= 1
end
end
end
sequence.reverse!
end
EDIT_COSTS = {
replace: 1,
insert: 1,
delete: 1,
}
def edit_distance(str1, str2)
str1, str2 = str1.downcase, str2.downcase
dp = Array.new(str1.length + 1) { Array.new(str2.length + 1) { 0 } }
costs = EDIT_COSTS
dp[0].map!.with_index { |_, i| i }
dp.each_with_index { |arr, j| arr[0] = j }
1.upto(str1.length) do |i|
1.upto(str2.length) do |j|
if str1[i - 1] == str2[j - 1]
dp[i][j] = dp[i - 1][j - 1]
else
dp[i][j] = [
costs[:insert] + dp[i][j - 1],
costs[:delete] + dp[i - 1][j],
costs[:replace] + dp[i - 1][j - 1]
].min
end
end
end
dp.last.last
end
def autocorrect(str)
dict = []
File.foreach("dictionary.txt") { |line| dict << line.chomp if line[0] == str[0] }
dict.min_by { |word| edit_distance(str, word) }
end