编辑距离

来源:互联网 发布:八度网络汪冕 编辑:程序博客网 时间:2024/05/16 18:34

问题:设A和B是两个字符串,要用最少的字符操作将字符串A转换成字符串B.

这里所说的字符串操作包括:

(1)删除一个字符;

(2)插入一个字符;

(3)将一个字符改为另一个字符;

将字符串A变换成字符串B所用的最少字符操作数成为字符串A到字符串B的编辑距离.

这个问题我们使用动态规划.动态规划的思想和分治法很像,都是将大问题化小,但是不一样的是,动态规划的子问题往往不是独立的,它总是由前一个的最优解来求下一个,因此也就解决了分治法所带来的重叠性问题

下面是代码

#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 100//找出最小值int mini(int a,int b,int c){int t;t=a<b?a:b;return t<c?t:c;}int EditDistance(char A[],char B[]){int m,n,i,j;int delet=0,insert=0,change=0;int Edit[N][N];int Min=0;m=strlen(A)+1;n=strlen(B)+1;for(i=0;i<m;i++)for(j=0;j<n;j++)Edit[i][j]=0;//初始化Edit[i][0]for(i=0;i<m;i++){Edit[i][0]=i;//printf("%3d",Edit[i][0]);}printf("\n");//初始化Edit[0][j]for(j=0;j<n;j++){Edit[0][j]=j;//printf("%3d",Edit[0][j]);}printf("\n");for(i=1;i<m;i++){for(j=1;j<n;j++){delet=Edit[i][j-1];delet+=1;//删除所得//printf("delete:%d\t",delet);insert=Edit[i-1][j];insert+=1;//插入所得//printf("insert:%d\t",insert);change=Edit[i-1][j-1];change+=(A[i-1]!=B[j-1]);//直接改变       // printf("\nchange:%d\n",change);Edit[i][j]=mini(delet,insert,change);    printf("%3d",Edit[i][j]);Min=Edit[i][j];}printf("\n");}return Min;}void main(){//char *str1;//char *str2;char A[N],B[N];int num; printf("请输入A,B字符串:\nA:");    //scanf("%s",str1);gets(A);printf("B:");//scanf("%s",str2);gets(B);num=EditDistance(A,B);    printf("%d\n",num);}
我们可以使用使用一个二维数组来存储每一次的结果,用A字符串的个数作为列数,B字符串的个数作为行数,当然每一行每一列都要加一,作为第0行第0列,然后我们就可以初始化如下图所示(假设从fxpimu变到xwrs)

         0    f    x    p    i    m    u

0    0    1   2    3    4    5     6

x    1

w   2

r    3

s    4

可以的看出Edit[i][j]=min{Edit[i][j-1]+1,Edit[i-1][j]+1,Edit[i-1][j-1]+f[i][j]};其中Edit[i][j-1]+1为插入步骤,Edit[i-1][j]+1为删除步骤,Edit[i-1][j-1]+f[i][j]为直接改变,其中如果两个字符串不等则f[i][j]=1,否则为0.

依次运算,得到最后一行最后一列即为最优解。




0 0
原创粉丝点击