[动态规划----基本DP]编辑距离 51nod 1183

来源:互联网 发布:微代言 源码 编辑:程序博客网 时间:2024/05/20 23:39

Part1 题意

编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将kitten一字转成sitting:
sitten (k->s)
sittin (e->i)
sitting (->g)
所以kitten和sitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
给出两个字符串a,b,求a和b的编辑距离。

Part2 思考过程

从表面上看这个题是个搜索题,根据这个思路可以用bfs+A*来做,这样做可能比较麻烦,但是是一条路线。第二种思想是动态规划的思想,每一次状态变动都是基于上一个状态进行的,简化问题,可以从头到尾进行状态的转移。对于两个字符串,完成前k个字符相同的前提是前k-1个字符相同,所以前k个字符相同状态可以从前k-1个字符相同的状态转移过来。有三种变化,如果增加或者删除,都是基于上一种状态的步数+1得到结果,如果是修改,则根据当前字符串的当前位置上的字符与另外一个字符串的对于位置上的字符的关系来取得,不相同+1,反之不加。

Part3 初步实现

注意点:
1、注意对DP矩阵进行初始化。
2、注意字符串的起始下标。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int dp[1010][1010];char str1[1010];char str2[1010];int len1,len2;int main(){    scanf("%s%s",str1,str2);    len1 = strlen(str1),len2 = strlen(str2);    for(int i=0;i<len1;i++) dp[i][0] = i;    for(int i=0;i<len2;i++) dp[0][i] = i;    for(int i=1;i<=len1;i++){        for(int j=1;j<=len2;j++){            dp[i][j]=min(dp[i-1][j-1]+(str1[i-1]!=str2[j-1]),min(dp[i][j-1],dp[i-1][j])+1);        }    }    printf("%d\n",dp[len1][len2]);    return 0;}

Part4 优化思想

与最长公共子序列的优化思想相同,可以将N2的空间复杂度优化到2*N的空间复杂度,用到循环数组,由于每一个点的值都只与其左、左上与上个位置中的位置,则可以将偶数行放置于一个两行数组的第一行,奇数行放置于一个两行数组的第二行,每次产生的新一行放置在对应的行数。由于现在空间复杂度的要求宽松不少,所以现在也不常用。

Part5 优化实现

原创粉丝点击