最高半折刷qq各种业务和钻(家里人自己开的,尽管放心,大家多捧捧场)

sking7

导航

字符串的编辑距离算法

在看一篇博文的时候看到了这么个算法,捉摸了很久才弄懂什么意思。
先解释下什么是编辑距离算法。
就是两个字符串(假如为S,T),从第一个字符串S,经过插入,删除,替换,添加,等操作数的总和数最小的路径称为字符串S和T的编辑距离。。。
以程序中的字符串为例:sting,cbstring1

1.首先创建一个二维矩阵,6 x 9,设为C[][]
首先初始化值。其实代表着初始化移动距离。。
2.进入循环,如果S的第一个字符串==T的第二个字符串,z=C[I][J],否则z=C[I+1][J+1]
其实就是记录操作数。z=0,或者z=1,最后记录到c[i=1][i=1],也就是说C,对应数组的值的是距离
但实例中不相等,则z=1,x=2,y=2,最后,C[1][1]=1;也就是说,到现在已经进行了距离为1的编辑。。
3.重新进入循环
i=0,j=1,这时
str1[i] == str2[j]仍然不成立。x=3,y=2,z=2,c[1][2]=2
4。进入循环
i=0,j=2,这时str1[i] == str2[j],成立,x=4,y=3,z=2
c[1][3]=2.
5.进入循环,i=0,j=3,这时不成立,x=5,y=3,z=4,c[1][4]=3.
6.i=0,j=4,不成立。x=6,y=4,z=5,c[1][5]=4;
//上面的步骤,相当于s到cbsting1前j个子字符串的编辑距离。
(有个算法是 这样的:见文章最后,引用1)
接着就是S的st二个字符串到cbsting1前J个子字符串的编辑距离。
二‘i=1.
1.i=1,j=0,不成立,x=2,y=3,z=2,c[2][1]=2
2.i=1,j=1,不成立,x=3,y=3,z=2,c[2][2]=2
3.i=1,j=2,成立,x=c[2][3]+1=2,y=c[2][2]+1=3;z=2;c[2][3]=2;
。。。。


0 1 2 3 4 5
1 1 2 2 3 4
2 2 2 2 2 3
3
4
5
6
7
8















其实总结下:
C[I][J],就是S的[0..i]字串到T[0..J]字串的编辑距离。
分解成C[I][J]=c[i-1][j]+1,c[i][j-1]+1,c[i-1][j-1]+f[i][j](见小注)
也就是
C[I+1][J+1]=c[i][j+1]+1,c[i+1][j]+1,c[i][j]+f[i+1][j+1]
下面是程序
package Algorithm;

public class Distance {
    public static void main(String[]args){
        int a=new Distance().getDistance("sting".toCharArray(),"cbsting1".toCharArray());
        System.out.println(a);
    }
    public int getDistance(char[] str1,char[] str2){
       
         int n = str1.length;
         int m = str2.length;
         int[][] C = new int[n+1][m+1];
         int i, j, x, y, z;
         for (i = 0; i <= n; i++)
             C[i][0] = i;
         for (i = 1; i <= m; i++)
             C[0] [i] = i;
         for (i = 0; i < n; i++)
             for (j = 0; j < m; j++)
             {
                 x = C[i][j + 1] + 1;
                 y = C[i + 1][ j] + 1;
                 if (str1[i] == str2[j])
                     z = C[i][ j];
                 else
                     z = C[i][ j] + 1;
                
                 C[i + 1][ j + 1] = Math.min(Math.min(x, y), z);
             }
         return C[n][ m];
     }
   
}

 

引用1:原文:http://hxraid.iteye.com/blog/615469

例如:S=“eeba”   T="abac" 我们发现当S只有一个字符e、T只有一个字符a的时候,我们马上就能得到S和T的编辑距离edit(0,0)=1(将e替换成a)。那么如果S中有1个 字符e、T中有两个字符ab的时候,我们是不是可以这样分解:edit(0,1)=edit(0,0)+1(将e替换成a后,在添加一个b)。如果S中有 两个字符ee,T中有两个字符ab的时候,我们是不是可以分解成:edit(1,1)=min(edit(0,1)+1, edit(1,0)+1, edit(0,0)+f(1,1)). 这样我们可以得到这样一些动态规划公式:      
        如果i=0且j=0        edit(0, 0)=1
        如果i=0且j>0        edit(0, j )=edit(0, j-1)+1
        如果i>0且j=0        edit( i, 0 )=edit(i-1, 0)+1
        如果i>0且j>0        edit(i, j)=min(edit(i-1, j)+1, edit(i,j-1)+1, edit(i-1,j-1)+f(i , j) )
小注
edit(i,j)表示S中[0.... i]的子串si到T中[0....j]的子串tj的编辑距离。

f(i,j)表示S中第i个字符s(i)转换到T中第j个字符s(j)所需要的操作次数,
如果s(i)==s(j),则不需要任何操作f(i, j)=0; 否则,需要替换操作,f(i, j)=1




posted on 2011-10-16 12:38  G.N&K  阅读(5779)  评论(0编辑  收藏  举报