看过网上的多篇文章,图示的基本都是列表格的,看的晕敷敷的。最终还是自己用动态规划的思想给推出来的,所以从基本思想入手,一点点推导,或许比直接看人家的推导结果更有效。
参考书籍:《Python程序员面试算法宝典》
用动态规划的思想分析。下面的操作均是执行在字符串s1上。
-
添加
假设,字符串s1的i个字符构成的字符串,和字符串s2的j-1个字符构成的字符串,两个字符串的编辑距离 D(i,j-1) 已知,即s1比s2少一个字符。那么只需s1的末尾添加字符s2[j]即可。s1[i]—(变换到)—>s2[j]的编辑距离为D(i,j) = D(i,j-1)+1。
-
删除
假设,字符串s1的前i-1个字符构成的字符串,和字符串s2的j个字符构成的字符串,两个字符串的编辑距离 D(i-1,j) 已知,即s1比s2多一个字符。那么只需删除s1的最后一个字符即可。s1[i]—(变换到)—>s2[j]的编辑距离为D(i,j) = D(i-1,j)+1。 -
替换
假设,字符串s1的前i-1个字符构成的字符串,和字符串s2的前j-1个字符构成的字符串,两个字符串的编辑距离 D(i-1,j-1) 已知,即s1与s2仅最后一个字符还没匹配。那么将s1变换到s2需要什么操作呢?- s1[i] == s2[j]
s1与s2的最后一个字符相同时,不需要进行操作。s1[i]—(变换到)—>s2[j]的编辑距离为D(i,j) = D(i-1,j)。 - s1[i]
̸
=
\not=
̸=s2[j]
s1与s2的最后一个字符不同时,只需将s1的最后一个字符替换为s2[j]。s1[i]—(变换到)—>s2[j]的编辑距离为D(i,j) = D(i-1,j)+1。
- s1[i] == s2[j]
综上,编辑距离的计算如下:
-
两个字符串中有空串
- 只有s1是空串,那么D(i,j)=j,即一直向s1添加字符。
- 只有s2是空串,那么D(i,j)=i。
- s1、s2都是空串,那么D(i,j)=0。
-
两个字符串都不是空串
s1、s2的最后一个字符可以通过如下方式,变换为相同。- 添加,D(i,j) = D(i-1,j)+1
- 删除,D(i,j) = D(i,j-1)+1
- 替换。最后一个字符相同时,D(i,j)=D(i-1,j-1)。最后一个字符不同时,D(i,j)=D(i-1,j-1)+1。
所以 D ( i , j ) = m i n { D ( i − 1 , j ) + 1 , D ( i , j − 1 ) + 1 , f ( i , j ) } D(i,j)=min\left\{D(i-1,j)+1,D(i,j-1)+1,f(i,j)\right\} D(i,j)=min{D(i−1,j)+1,D(i,j−1)+1,f(i,j)},当s1[i]==s[j]时,f(i,j)==D(i-1,j-1)。当s1[i] ̸ = \not= ̸=s[j]时,f(i,j)=D(i-1,j-1)+1。