编辑距离的概念
给定两个字符串 A A A和 B B B,使用以下三种操作将前者变为后者:
- 插入(Insert)
- 删除(Delete)
- 替换(Replace)
每做一次操作,编辑次数加一,最终所做操作次数即为编辑距离,记为 D i s t a n c e ( A , B ) Distance(A,B) Distance(A,B),简写为 D ( A , B ) D(A,B) D(A,B)。
求解最小编辑距离
将字符串 A A A变为 B B B,存在多种解决方案,我们需要找到操作次数最少的解决方案(最小编辑距离),该问题可使用动态规划(dynamic programing)的思想。为方便书写,首先将 A A A和 B B B表示为如下形式:
- A = A ( m ) = A 1 A 2 . . . A m A=A^{(m)}=A_{1}A_{2}...A_{m} A=A(m)=A1A2...Am
- B = B ( n ) = B 1 B 2 . . . B n B=B^{(n)}=B_{1}B_{2}...B_{n} B=B(n)=B1B2...Bn
其次讨论以下两种情况:
- 若 A m A_{m} Am, B n B_{n} Bn不相等, D ( A , B ) = m i n [ D ( A ( m − 1 ) , B ( n − 1 ) ) , D ( A ( m − 1 ) , B ( n ) ) , D ( A ( m ) , B ( n − 1 ) ) ] + 1 D(A,B)=min\left[D\left(A^{(m-1)},B^{(n-1)}\right),D\left(A^{(m-1)},B^{(n)}\right),D\left(A^{(m)},B^{(n-1)}\right)\right]+1 D(A,B)=min[D(A(m−1),B(n−1)),D(A(m−1),B(n)),D(A(m),B(n−1))]+1
- 若 A m A_{m} Am, B n B_{n} Bn相等, D ( A , B ) = D ( A ( m − 1 ) , B ( n − 1 ) ) D(A,B)=D(A^{(m-1)},B^{(n-1)}) D(A,B)=D(A(m−1),B(n−1))
应用
下面展示如何使用动态规划来求解oppa、apple之间的最小编辑距离。
1、初始化
a | p | p | l | e | ||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | |
o | 1 | |||||
p | 2 | |||||
p | 3 | |||||
a | 4 |
首先在每个字符串的前面添加一个空格(也可以叫空串)。这么做的理由是,按照转移方程 D ( A , B ) = m i n [ D ( A ( m − 1 ) , B ( n − 1 ) ) , D ( A ( m − 1 ) , B ( n ) ) , D ( A ( m ) , B ( n − 1 ) ) ] + 1 D(A,B)=min\left[D\left(A^{(m-1)},B^{(n-1)}\right),D\left(A^{(m-1)},B^{(n)}\right),D\left(A^{(m)},B^{(n-1)}\right)\right]+1 D(A,B)=min[D(A(m−1),B(n−1)),D(A(m−1),B(n)),D(A(m),B(n−1))]+1求解 D ( A , B ) D(A,B) D(A,B),需要先求解子问题(也即初始化)。
a | ||
---|---|---|
0 | 1 | |
o | 1 |
以上述表格举例。
- 空格变成空格,需要0次编辑
- 空格变成a,需要1次编辑(添加)
- o变成空格,需要1次编辑(删除)
2、依次求解
a | p | p | l | e | ||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | |
o | 1 | ? | ||||
p | 2 | |||||
p | 3 | |||||
a | 4 |
问号处应填入1,因为,o与a不相等,按照 D ( A , B ) = m i n [ D ( A ( m − 1 ) , B ( n − 1 ) ) , D ( A ( m − 1 ) , B ( n ) ) , D ( A ( m ) , B ( n − 1 ) ) ] + 1 D(A,B)=min\left[D\left(A^{(m-1)},B^{(n-1)}\right),D\left(A^{(m-1)},B^{(n)}\right),D\left(A^{(m)},B^{(n-1)}\right)\right]+1 D(A,B)=min[D(A(m−1),B(n−1)),D(A(m−1),B(n)),D(A(m),B(n−1))]+1左上、左、上三个格子中最小的是左上0,0+1=1,所以问号处填入1。从左上选取意味着做了如下操作:
- o前面的空串经过0次编辑变成了a前面的空串
- 将o替换为a
a | p | p | l | e | ||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | |
o | 1 | 1 | ? | |||
p | 2 | |||||
p | 3 | |||||
a | 4 |
问号处应填入2,因为,o与p不相等,按照 D ( A , B ) = m i n [ D ( A ( m − 1 ) , B ( n − 1 ) ) , D ( A ( m − 1 ) , B ( n ) ) , D ( A ( m ) , B ( n − 1 ) ) ] + 1 D(A,B)=min\left[D\left(A^{(m-1)},B^{(n-1)}\right),D\left(A^{(m-1)},B^{(n)}\right),D\left(A^{(m)},B^{(n-1)}\right)\right]+1 D(A,B)=min[D(A(m−1),B(n−1)),D(A(m−1),B(n)),D(A(m),B(n−1))]+1左上、左、上三个格子中最小的是左上或者左,1+1=2,所以问号处填入2。不同的选择代表了不同的操作。
- 如果从左上选取,即做如下操作,1.将o前面的空串替换成a。2.将o替换为p。
- 如果是从左选取的,即做如下操作,1.将o替换成a。2.添加一个p。
以下省略若干步。
a | p | p | l | e | ||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | |
o | 1 | 1 | 2 | 3 | 4 | 5 |
p | 2 | 2 | 1 | ? | ||
p | 3 | |||||
a | 4 |
问号处应填入2,因为p与p相等,所以直接采用左上角的结果。最终结果如下图所示。
a | p | p | l | e | ||
---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | |
o | 1 | 1 | 2 | 3 | 4 | 5 |
p | 2 | 2 | 1 | 2 | 3 | 4 |
p | 3 | 3 | 2 | 1 | 2 | 3 |
a | 4 | 3 | 3 | 2 | 2 | 3 |