动态规划之编辑距离问题

由公式可以看出,(i-1,j)对应删除操作,(i,j-1)对应插入操作。
可以这样理解,现在耗费了di-1,j步操作将字符串a(1,i-1)转换成了b(1,j),则在将a(1,i)转换成b(1,j)时,我们可以直接删掉字符a(i),
问题变成a(1,i-1)转换成b(1,j),从而dij就等于di-1,j+1。同理,现在耗费了di,j-1步操作将字符串a(1,i)转换成了b(1,j-1),
则在将a(1,i)转换成b(1,j)时,我们可以将b(j)添加到a(1,i)末尾(此时a(1,i)已转换成b(1,j-1))构成b(1,j)。对应的代码实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int dist[100][100];//表示长度为i的字符串变为长度为j的字符串需要的编辑距离
int MIN(int i,int j)
{
    if(i>j)
        return j;
    else
        return i;
}
int edit_distance(char* a,char* b)
{
    int i,j;
    int len_a=strlen(a);
    int len_b=strlen(b);
    printf("%d %d \n",len_a,len_b);
    //b为空字符串,将a变为b需要不停地删除a的字符
    for ( i=0;i<=len_a;i++)
    {
        dist[i][0]=i;
    }

    //a为空字符串,将a变为b需要不停地添加b的字符
    for ( j=0;j<=len_b;j++)
    {
        dist[0][j]=j;
    }

    for ( i=1;i<=len_a;i++)
    {
        for ( j=1;j<=len_b;j++)
        {
            int cost = (a[i-1] == b[j-1] ? 0 : 1);      /******/

            int deletion = dist[i-1][j] + 1;         //删除
            int insertion = dist[i][j-1] + 1;        //插入
            int substitution = dist[i-1][j-1] + cost;//变换/不动

            dist[i][j] = MIN(deletion,MIN(insertion,substitution));
        }
    }

    for(i=0;i<=len_a;i++)
    {
        for(j=0;j<=len_b;j++)
        {
            printf("%d ",dist[i][j]);
        }
        printf("\n");
    }
    return dist[len_a][len_b];
}

int main()
{
    char a[8] = "abc";
    char b[6] = "cba";
    int result = edit_distance(a,b);
    printf("%d\n",result);

    //printf("%d\n",dist[1][1]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38605328/article/details/83621705