Chinaunix首页 | 论坛 | 博客
  • 博客访问: 342113
  • 博文数量: 122
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 1191
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 11:12
文章分类

全部博文(122)

文章存档

2010年(122)

我的朋友

分类: C/C++

2010-03-01 19:36:25

 

资源来源:http://blog.chinaunix.net/u3/105033/index.html

 

 

一、问题描述

AB是两个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:

  1)删除一个字符;

  2)插入一个字符;

  3)将一个字符改为另一个字符;

  将字符串A变换为字符串B所用的最少字符操作数称为字符串AB的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的两个字符串AB,计算出它们的编辑距离d(A,B)

 

二、分析解答

设所给的两个字符串为A[1:m]B[1:n]。定义D[i][j]=d(A[1:i],B[1,j])。单字符a,b间的距离定义为:

d(a,b)=0 (a=b)

d(a,b)=1(a!=b)

考察从字符串A[1:i]到字符串B[1:j]的变换。可分成以下几种情况:
1)字符A[i]改为字符B[j];需要d(A[i],B[j])次操作。

2)删除字符A[i];需要1次操作。

3)插入字符B[j];需要1次操作。
因此,D[i][j]可递归地计算如下。

D[i][j]=min{D[i-1][j-1]+d(A[i],B[j]),D[i-1][j]+1,D[i][j-1]+1}

 

三、算法描述

int dist(A[0…m-1],B[0…n-1])

{

int D[0…m,0…n]

int i,j,cost

对于i等于0m

D[i, 0]=i

对于j等于0n

D[0,j]=j

对于i等于1m

    对于j等于1n

        A[i-1]=B[j-1]cost=0 否则 cost=1

        D[i][j]=min(D[i-1,j]+1,//删除

                    D[i,j-1]+1,//插入

                    D[i-1,j-1]+cost//替换

                     )

返回d[m,n]

}

 

四、代码实现

定义一个二维数组D[][]存储中间结果,如下图所示,为已经初始化后的情况。然后从D[1,1]开始从左到右,从上到下依次按填表,表的最后一个元素D[m,n]就是要求的最终结果。

 

0

1

2

3

4

5

6

0

0

1

2

3

4

5

6

1

1

 

 

 

 

 

2

2

 

 

 

 

 

 

3

3

 

 

 

 

 

 

4

4

 

 

 

 

 

 

5

5

 

 

 

 

 

 

6

6

 

 

 

 

 

 

 

#include<iostream>
#include<string>
using namespace std;
int D[100][100];
int dis[100];
int min(int a,int b,int c)
{
    return c<(a>b?b:a)?c:(a>b?b:a);
}
int dist(char * A,char * B)
{
    int m=strlen(A);
    int n=strlen(B);
    int i,j;

    for(i=0;i<=m;++i)
    {
        D[i][0]=i;
    }
    for(j=0;j<=n;++j)
    {
        D[0][j]=j;
    }
    int cost;
    for(i=1;i<=m;++i)
    {
        for(j=1;j<=n;++j)
        {
            if(A[i-1]==B[j-1])
                cost=0;
            else
                cost=1;
            D[i][j]=min(D[i-1][j-1]+cost,D[i-1][j]+1,D[i][j-1]+1);
        }
    }
    return D[m][n];
}
int dist2(char * A,char * B)
{
    int m=strlen(A);
    int n=strlen(B);
    int i,j;
    for(i=0;i<=n;++i)
        dis[i]=i;
    int cost;
    for(i=1;i<=m;++i)
    {
        int y=i-1;
        for(j=1;j<=n;++j)
        {
            int x=y;
            y=dis[j];
            int z=j>1?dis[j-1]:i;
            cost=A[i-1]==B[j-1]?0:1;
            dis[j]=min(x+cost,y+1,z+1);
        }
    }
    return dis[n];
}
int main(int argc, char* argv[])
{    
    char * ch1="bcdefghijklmnopq";
    char * ch2="abcdefghijklmnopadfsafwe";
    cout<<dist(ch1,ch2)<<endl;
    cout<<dist2(ch1,ch2)<<endl;
    return 0;
}


五、优化方法

从上面算法可以看出,该算法时间复杂性为0(m*n),空间复杂性为Om*n)。同时可以看出,当对第i行进行填表时,只需要用到第i-1行的数据,因此可以用一个一维数组dis[0…n]代替二维数组D[0…m,0…n],因此空间复杂性降为O(n)。实现代码如上面函数dist2()所示。

阅读(1856) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:POJ 1844 Sum 解题报告

给主人留下些什么吧!~~