思考:我们可以从题目中给出的6种操作描述,找到递归式,比如复制操作是i和j都增加1。那么递归式就是c[i][j]=c[i-1][j-1]+cost[COPY]。c[i][j]表示从字符串i复制到字符串j所需要的总代价。其他操作类似。
递归式如下:
代码如下:
#include
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-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-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-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-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-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[i][n]+cost[KILL];
t.op[m][n]=i;
}
}
cout<
for (i=0;i<=m;i++)
{
for ( j=0;j<=n;j++)
{
cout<
}
cout<
}
cout<
for (i=0;i<=m;i++)
{
for (int j=0;j<=n;j++)
{
cout<
}
cout<
}
cout<
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<
}
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即可。