假设给定两个字符串str1和str2,如果我们想把str1变为str2,这一过程中所需的最少的插入、删除和替换等基本操作的个数称为str1与str2之间的编辑距离。比如如果想把字符串abandon变为aband最好的方案是删除on这两个字母,因而它们之间的编辑距离就是2;同样如果想把abandon变为abanded最优的方案是把最后的on替换为ed,需要替换两个字母,所以它们之间的编辑距离也是2。
求解两个字符串之间的编辑距离可以使用动态规划的方法。首先定义一个函数,它表示第一个字符串str1长度为的子串到第二个字符串str2长度的子串的编辑距离。这里说的子串都是指str1和str2的从头开始长度和的子串。可以有以下动态规划公式:
- 如果 i=0 并且 j=0, 则=0
- 如果 i=0 并且 j>0, 则=j
- 如果 i>0 并且 j=0, 则=i
- 如果 i>0 并且 j>0, 则
其中第4种情况中min中的三个式子分别对应需要对str1进行删除、插入和替换操作。是指将str1的第i位与第j位进行比较,如果相同则值为1,不同则为0。
下面给出了该方法的Python程序实现。
import numpy as np
def string_distance(str1, str2):
"""
计算两个字符串之间的编辑距离
@author: 仰起脸笑的像满月
@date: 2019/05/15
:param str1:
:param str2:
:return:
"""
m = str1.__len__()
n = str2.__len__()
distance = np.zeros((m+1, n+1))
for i in range(0, m+1):
distance[i, 0] = i
for i in range(0, n+1):
distance[0, i] = i
for i in range(1, m+1):
for j in range(1, n+1):
if str1[i-1] == str2[j-1]:
cost = 0
else:
cost = 1
distance[i, j] = min(distance[i-1, j]+1, distance[i, j-1]+1, distance[i-1, j-1]+cost) # 分别对应删除、插入和替换
return distance[m, n]
if __name__ == '__main__':
a = 'abandon'
b = 'abanded'
result = string_distance(a, b)
print(result)