转自:http://blog.sina.com.cn/s/blog_6473891f0100grx6.html
一、问题描述
设A和B是两个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:
二、分析解答
设所给的两个字符串为A[1:m]和B[1:n]。定义D[i][j]=d(A[1:i],B[1,j])表示将A[1:i]转换为B[1:j]需要的代价。
单字符a,b间的距离定义为:
d(a,b)=0 (a=b)
d(a,b)=1(a!=b)
考察从字符串A[1:i]到字符串B[1:j]的变换。假设我们已经执行到最后一步,即A[i]<-->B[j]需要执行的操作。
可分成以下几种情况:
(1)字符A[i]改为字符B[j];需要d(A[i],B[j])次操作,需要的代价是D[i-1,j-1]+d(A[i],B[j])。
(2)删除字符A[i];B不需要动,需要1次操作。代价为:D[i-1,j]+1
(3)插入字符B[j],A不需要动;需要1次操作。代价:D[i,j-1]+1
因此,D[i][j]可递归地计算如下。
D[i][j]=min{D[i-1][j-1]+d(A[i],B[j]),D[i-1][j]+1,D[i][j-1]+1}。
三、算法描述
int dist(A[0…m-1],B[0…n-1])
{
int D[0…m,0…n]
int i,j,cost
对于i等于0至m
D[i, 0]=i
对于j等于0至n
D[0,j]=j
对于i等于1至m
返回d[m,n]
}
四、代码实现
定义一个二维数组D[][]存储中间结果,如下图所示,为已经初始化后的情况。然后从D[1,1]开始从左到右,从上到下依次按填表,表的最后一个元素D[m,n]就是要求的最终结果。
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
1 | 1 | | | | | | |
2 | 2 | | | | | | |
3 | 3 | | | | | | |
4 | 4 | | | | | | |
5 | 5 | | | | | | |
6 | 6 | | | | | | |
|
五、优化方法
从上面算法可以看出,该算法时间复杂性为0(m*n),空间复杂性为O(m*n)。同时可以看出,当对第i行进行填表时,只需要用到第i-1行的数据,因此可以用一个一维数组dis[0…n]代替二维数组D[0…m,0…n],因此空间复杂性降为O(n)。实现代码如上面函数dist2()所示。