diif

对于给定的两个字符串,diff就是找出这两个字符串的最小差别,即最短的编辑距离,例如:
S1: a b c d a
S2: a c d a
S1与S2的diff就是S2缺少一个b,最短的编辑距离也就是在S2插入一个b

这个问题与字符串的最长公共字串是等价的,假设S1与S2的公共字串为{(Xi1,Yj1),...,(Xin,Yjn)},i1 < in
编辑距离为删除从S1中删除Xik与Xik+1中的字符并且插入Yik与Yik+1之间的字符,这个距离是最短的,因此diff和求最长公共字串的问题是等价的

Meyer给出了一个贪心的解,该算法的时间复杂度为o(ND),其中n为字符串的长度,D为差异
该算法如下:
以待比较的两个字符串组成一个矩阵,对该矩阵的每一个坐标定义一个值k=x-y,一个比较结果可以看着对两个串的移动,同时移动两个串,移动一个串,移动另一个串,因此对应到矩阵上就是移动到对角(x++,y++),或者(x++,y),或者(x,y++),我们可以得到如下结论,因此从(0,0)到(n,m)的一条路径就代表了一个比较结果,假设路径包含了D条非对角线的路径,那么这条路径的终点肯定是{-D,-D+2,....D-2,D},可以证明如下:数学归纳法很好证明的,从Dpath到D+1,只有两种方式,x++或者y++,如果x++,因此终点是{-D+/1(加减) 1,...,D+/ 1},因此是{-D-1,-D+1,...,D+1},因此得证。
Dpath的组成可以看做如下:D-1path的末尾以对角结尾,Dpath以x++或者y++开始,接着一个对角串,因此贪心算法为D-1path尽量地远,当某条Dpath到达边界时,算法结束,找到边界。

证明如下:首先是一个直观的理解,当D-1path没有达到最远的时候,如下:
a b c d d a b c
a b c d a b c
d0的终点如果是(c,c),d1的终点也会是最后的两个断点,与d0到达(d,d)是等价的
正式的证明如下:如果D-1不是最远的,那么从一个最远的D-1出发总能通过适当的移动达到最远。!

基于上面的描述一个求diff的过程可以如下:
一个终点为k的DPath,肯定是从终点为k+/ 1的D-1 PATH移动过来的,因此求diff的伪码如下:
for d from 0 to M+N
  for k from -d to d step 2
     find the endpoint of the furthest reaching d-path in diagonal k
     if reaches (N,M)
         find the optimal

改进的代码如下:
1. V[1] = 0                 
2. For D = 0 to MAX Do
3. For k = -D to D in steps of 2 Do
4. If k = -D or k ¹ D and V[k - 1] < V[k + 1] Then
5.     x  = V[k + 1]                  //计算最远的d path的终点为k,从最远的d-1path出发
6. Else
7. x  =  V[k - 1]+1
8. y = x - k
9. While x < N and y < M and a x + 1 = by + 1 Do (x,y) = (x+1,y+1)
10. V[k] = x
11. If x  =  N and y  = M Then
12. Length of an SES is D
13. Stop
14. Length of an SES is greater than MAX

v是一个数组,用来存放每一条路径的终点,由于d path的终点只能是-d到d,所以v的大小为2d,并且v[k]存放终点为k的x坐标,v[1] = 0 存放的是初始化的-1 path,用于计算0path时的值

你可能感兴趣的:(c,算法,Path)