1. 程式人生 > >動態規劃之編輯距離問題

動態規劃之編輯距離問題

由公式可以看出,(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;
}