動態規劃之編輯距離問題
由公式可以看出,(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;
}