1.百度百科介紹:
Levenshtein 距離,又稱編輯距離,指的是兩個字符串之間,由一個轉換成另一個所需的最少編輯操作次數。
許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。
編輯距離的算法是首先由俄國科學家Levenshtein提出的,故又叫Levenshtein Distance。
2.用途
模糊查詢
3.實現過程
a.首先是有兩個字符串,這裏寫一個簡單的 abc和abe
b.將字符串想象成下面的結構。
A處 是一個標記,爲了方便講解,不是這個表的內容。
abc | a | b | c | |
abe | 0 | 1 | 2 | 3 |
a | 1 | A處 | ||
b | 2 | |||
e | 3 |
c.來計算A處 出得值
它的值取決於:左邊的1、上邊的1、左上角的0.
按照Levenshtein distance的意思:
上面的值和左面的值都要求加1,這樣得到1+1=2。
A處 由於是兩個a相同,左上角的值加0.這樣得到0+0=0。
這是後有三個值,左邊的計算後爲2,上邊的計算後爲2,左上角的計算爲0,所以A處 取他們裏面最小的0.
d.於是表成爲下面的樣子
abc | a | b | c | |
abe | 0 | 1 | 2 | 3 |
a | 1 | 0 | ||
b | 2 | B處 | ||
e | 3 |
在B處 會同樣得到三個值,左邊計算後爲3,上邊計算後爲1,在B處 由於對應的字符爲a、b,不相等,所以左上角應該在當前值的基礎上加1,這樣得到1+1=2,在(3,1,2)中選出最小的爲B處的值。
e.於是表就更新了
abc | a | b | c | |
abe | 0 | 1 | 2 | 3 |
a | 1 | 0 | ||
b | 2 | 1 | ||
e | 3 | C處 |
C處 計算後:上面的值爲2,左邊的值爲4,左上角的:a和e不相同,所以加1,即2+1,左上角的爲3。
在(2,4,3)中取最小的爲C處 的值。
f.於是依次推得到
a | b | c | ||
0 | 1 | 2 | 3 | |
a | 1 | A處 0 | D處 1 | G處 2 |
b | 2 | B處 1 | E處 0 | H處 1 |
e | 3 | C處 2 | F處 1 | I處 1 |
I處: 表示abc 和abe 有1個需要編輯的操作。這個是需要計算出來的。
同時,也獲得一些額外的信息。
A處: 表示a 和a 需要有0個操作。字符串一樣
B處: 表示ab 和a 需要有1個操作。
C處: 表示abe 和a 需要有2個操作。
D處: 表示a 和ab 需要有1個操作。
E處: 表示ab 和ab 需要有0個操作。字符串一樣
F處: 表示abe 和ab 需要有1個操作。
G處: 表示a 和abc 需要有2個操作。
H處: 表示ab 和abc 需要有1個操作。
I處: 表示abe 和abc 需要有1個操作。
g.計算相似度
先取兩個字符串長度的最大值maxLen,用1-(需要操作數除maxLen),得到相似度。
例如abc 和abe 一個操作,長度爲3,所以相似度爲1-1/3=0.666。
4.lua代碼實現
strA = {"今", “天”, “是”, “星”, “期”, “四”}
strB = {"今", “天”, “是”, “星”, “期”,“(”, “四”, “)”}
結果是75%
function levenshtein(strA, strB)
local tempTb = {}
for m = 1, (#strA + 1), 1 do
tempTb[m] = {}
tempTb[m][1] = m - 1
end
for n = 1, (#strB + 1), 1 do
tempTb[1][n] = n - 1
end
for i = 2, (#strA + 1) , 1 do
for j = 2, (#strB + 1), 1 do
local x = tempTb[i - 1][j] + 1 --刪除
local y = tempTb[i][j - 1] + 1 --插入
local z = 0
if strA[i - 1] == strB[j - 1] then --替換
z = tempTb[i -1][j - 1]
else
z = tempTb[i -1][j - 1] + 1
end
tempTb[i][j] = math.min(x,y,z)
end
end
return (1- tempTb[#strA + 1][#strB + 1]/math.max(#strA, #strB))*100
end
5.猜測原理
爲什麼這樣就能算出相似度了?
首先在連續相等的字符就可以考慮到
紅色是取值的順序。
1.今天週一 天週一
天 | 周 | 一 | ||
0 | 1 | 2 | 3 | |
今 | 1 | 1 | 2 | 3 |
天 | 2 | 1 | 2 | 3 |
周 | 3 | 2 | 1 | 3 |
一 | 4 | 3 | 3 | 1 |
實現是去掉“今”,一步完成。
2.聽說馬上就要放假了 你聽說要放假了
你 | 聽 | 說 | 要 | 放 | 假 | 了 | ||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
聽 | 1 | 1 | 1 | 2 | 3 | 4 | 5 | 6 |
說 | 2 | 2 | 2 | 1 | 2 | 3 | 4 | 5 |
馬 | 3 | 3 | 3 | 2 | 2 | 3 | 4 | 5 |
上 | 4 | 4 | 4 | 3 | 3 | 3 | 4 | 5 |
就 | 5 | 5 | 5 | 4 | 4 | 4 | 4 | 5 |
要 | 6 | 6 | 6 | 5 | 4 | 5 | 5 | 5 |
放 | 7 | 7 | 7 | 6 | 5 | 4 | 5 | 6 |
假 | 8 | 8 | 8 | 7 | 6 | 5 | 4 | 6 |
了 | 9 | 9 | 9 | 8 | 7 | 6 | 6 | 4 |
這兩個字符串是:
去掉“你”,加上“馬上就”,總共四步操作。