动态规划之编辑距离

Posted Flammable_ice

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划之编辑距离相关的知识,希望对你有一定的参考价值。

思考:我们可以从题目中给出的6种操作描述,找到递归式,比如复制操作是i和j都增加1。那么递归式就是c[i][j]=c[i-1][j-1]+cost[COPY]。c[i][j]表示从字符串i复制到字符串j所需要的总代价。其他操作类似。

递归式如下

代码如下

#include <iostream>
using namespace std;
enum COPY,REPLACE,DELETE,INSERT,TWIDDLE,KILL,ENUM_MAX;//TWIDDLE旋转
struct T

   int **c,**op;
   T(int m,int n)
   
	   c=new int*[m+1];
	   for ( int i=0;i<=m;i++)
	   
		   c[i]=new int[n+1];
	   
	   op=new int*[m+1];
	   for ( i=0;i<=m;i++)
	   
		   op[i]=new int[n+1];
	   
   
;
struct T EDIT_DISTANCE(char x[],char y[],int m,int n)

	int i,j;
	struct T t(m,n);
	int cost[ENUM_MAX]=-1,1,2,2,-2,1;
	t.c[0][0]=0;
	for ( i=0;i<=m;i++)
	
		t.c[i][0]=i*cost[DELETE];
		t.op[i][0]=DELETE;
	
	for (j=0;j<=n;j++)
	
		t.c[0][j]=j*cost[INSERT];
		t.op[0][j]=INSERT;
	
	for (i=1;i<=m;i++)
	
		for (j=1;j<=n;j++)
		
			t.c[i][j]=0x7fffffff;
			if (x[i]==y[j]&&t.c[i-1][j-1]+cost[COPY]<t.c[i][j])
			
				t.c[i][j]=t.c[i-1][j-1]+cost[COPY];
				t.op[i][j]=COPY;
			
			if (x[i]!=y[j]&&t.c[i-1][j-1]+cost[REPLACE]<t.c[i][j])
			
				t.c[i][j]=t.c[i-1][j-1]+cost[REPLACE];
				t.op[i][j]=REPLACE;
			
			if (i>=2&&j>=2&&x[i]==y[j-1]&&x[i-1]==y[j]&&t.c[i-2][j-2]+cost[TWIDDLE]<t.c[i][j])
			
               t.c[i][j]=t.c[i-2][j-2]+cost[TWIDDLE];
			   t.op[i][j]=TWIDDLE;
			
			if (t.c[i-1][j]+cost[DELETE]<t.c[i][j])
			
				t.c[i][j]=t.c[i-1][j]+cost[DELETE];
				t.op[i][j]=DELETE;
			
			if (t.c[i][j-1]+cost[INSERT]<t.c[i][j])
			
				t.c[i][j]=t.c[i][j-1]+cost[INSERT];
				t.op[i][j]=INSERT;
			
		
	
	for ( i=0;i<=m-1;i++)
	
		if (t.c[i][n]+cost[KILL]<t.c[m][n])
		
			t.c[m][n]=t.c[i][n]+cost[KILL];
			t.op[m][n]=i;
		
	
	cout<<"c[m][n]="<<t.c[m][n]<<" "<<endl;
	for (i=0;i<=m;i++)
	
		for ( j=0;j<=n;j++)
		
			cout<<t.c[i][j]<<"  ";
		
		cout<<endl;
	
	cout<<endl;
	for (i=0;i<=m;i++)
	
		for (int j=0;j<=n;j++)
		
			cout<<t.op[i][j]<<"  ";
		
		cout<<endl;
	
	cout<<endl;
	return t;

void OP_SEQUENCE(struct T t,int i,int j)

	int I,J;
    if(i==0&&j==0)return;
	if (t.op[i][j]==COPY||t.op[i][j]==REPLACE)
	
        I=i-1;
		J=j-1;
	 
	else if(t.op[i][j]==TWIDDLE)
	
		I=i-2;
		J=j-2;
	
	else if (t.op[i][j]==DELETE)
	
		I=i-1;
		J=j;
	
	else if (t.op[i][j]==INSERT)
	
		I=i;
		J=j-1;
	
	else
	
		I=t.op[i][j];
		J=j;
		t.op[i][j]=KILL;
	
	OP_SEQUENCE(t,I,J);
	cout<<t.op[i][j]<<" ";

void main()

	char x[] = " algorithm";  
	char y[] = " altruistic";  
	int m = strlen(x), n = strlen(y);  
	struct T t=EDIT_DISTANCE(x,y,m,n);
	OP_SEQUENCE(t,m,n);
总结: 这个和求LCS类似。运行时间为O(mn)。理解了LCS这个应该没问题。还有注意初始化和最后操作kill即可。

以上是关于动态规划之编辑距离的主要内容,如果未能解决你的问题,请参考以下文章

怎样衡量两个字符串的相似度(编辑距离动态规划求解)

动态规划之寻找编辑距离

动态规划经典题之编辑距离

动态规划法算法之编辑距离

bzoj 4585 烟火表演 - 动态规划 - 可并堆

376,动态规划之编辑距离