1、编辑距离问题,河南省实验中学 彭勃,题目描述假设字符串的基本操作仅为:删除一个字符、插入一个字符和将一个字符修改成另一个字符这三种操作。 我们把进行了一次上述三种操作的任意一种操作称为进行了一步字符基本操作。 下面我们定义两个字符串的编辑距离:对于两个字符串a和b,通过上述的基本操作,我们可以把a变成b或b变成a,那么字符串a变成字符串b需要的最少基本字符操作步数称为字符串a和字符串b的编辑距离。 例如:a=“ABC”,b=“CBCD”,则a与b的编辑距离为2。 你的任务就是:编写一个快速的程序来计算任意两个字符串的编辑距离。 输入输入包含两行:第一行为字符串A,第二行为字符串B。 字符串的长
2、度不大于10000,且全为字母。 输出输出只有一行,为编辑距离。 样例输入ABC CBCD 样例输出2,题目分析,乍一看仿佛是搜索,但仔细一想,这道题用搜索是不可能实现的(至少我是这么认为的)。那么我们就要采取新的策略:动态规划。 我们知道,所有的动规问题都是可以分段解决的,那么这道题也是如此。我们可以把长的字符串拆解为短的字符串,一直拆解到只剩下一个字符为止。,动态转移方程的推导,判断啊a、b两个字符的编辑距离十分简单:若a=b则编辑距离为0;反之则为1 计算字符a与长度为二的字符串b的编辑距离也不难:首先计算a与b1的编辑距离,记为f,再判断a与b2是否相同,相同则最终编辑距离为f,不同则
3、为f+1。若b的长度大于2,则该规律依然成立。 注意:这里出现问题了:假如a=a,b=aa,则它们的编辑距离应为1,但通过上述计算得到的结果为0。,注意,这里我们要明确一点,对于任意两字符串a、b,它们的编辑距离不可能小于它们的长度之差的绝对值。因为对于三种基本操作,它们对字符串长度的影响为1(插入和删除)或0(修改)。 举一个例子:a的长度la=9,b的长度lb=15 则a、b的编辑距离mabs(la-lb) 即m6,动态转移方程的推导,解决了上面一个问题,我们继续。 刚才我们已经分析出了两个字符的编辑距离和一个字符与一个字符串的编辑距离,接下来便是两个字符串的编辑距离。 假如a=ab,b=
4、cd,则一眼就可以看出编辑距离m=2。这是没有重复字母的情况下。 但是如果有重复字母呢?,动态转移方程的推导,若a=ab,b=bc,则它们的编辑距离m=2 若a=ab,b=cb,则它们的编辑距离m=1 若a=ab,b=ab,则它们的编辑距离m=0 若a=abc,b=cba,则它们的编辑距离m=2 若a=abc,b=cab,则它们的编辑距离m=2 若a=abc,b=bac,则它们的编辑距离m=2 若a=abc,b=bcd,则它们的编辑距离m=2 这有什么规律呢?,动态转移方程的推导,我们把上面的几种情况绘成表格:,动态转移方程,通过观察表格我们可以发现以下规律: 对于表格f,fj,k表示a的前j
5、个字符到b的前k个字符的编辑距离 若ajbk 则fj,k为fj-1,k-1、fj-1,k、fj,k-1三个数中最小数+1 若aj=bk 则fj,k=fj-1,k-1 最终结果为fla,lb(la、lb为字符串长度),边界问题,对于方程 若j=1且k1则fj,k=fj,k-1+1 若k=1且j1则fj,k=fj-1,k+1 若j=1且k=1则f1,1=1 对于方程 若j=1且k1则fj,k=fj,k-1 若k=1且j1则fj,k=fj-1,k 若k=1且j=1则f1,1=0,程序设定,program bjjl; consti_f=bjjl.in;o_f=bjjl.out;maxx=10000;
6、typesz=array1maxxof char;dt=array1maxx,1maxx of integer; vara,b:sz;f:dt;la,lb,j,k:integer;,数组长度存放字符串,string型存不到1万 动态规划二维表a、b字符串 动规二维表 la、lb字符串长度,j、k循环控制变量,min函数,function min:integer; var t:integer; beginif (j=1)and(k=1) then min:=0else if j=1 then min:=fj,k-1else if k=1 then min:=fj-1,kelse beginif
7、fj-1,kfj,k-1 then t:=fj,k-1else t:=fj-1,k;if fj-1,k-1t then min:=fj-1,k-1else min:=t; end; end;,用于方程 t:临时变量这三行是处理边界问题找最小,fid函数,function fid:integer; var t:integer; beginif (j=1)and(k=1) then t:=0else if j=1 then t:=fj,k-1else if k=1 then t:=fj-1,kelse t:=fj-1,k-1;if tabs(j-k) then fid:=abs(j-k)else fid:=t; end;,用于方程 t:临时变量处理边界问题处理注意事项,程序主体,la:=0; lb:=0; repeat inc(la); read(ala); until eoln; readln(b1); repeat inc(lb); read(blb); until eoln; for j:=1 to la dofor k:=1 to lb doif aj=bk then fj,k:=fidelse fj,k:=min+1; writeln(fla,lb);,初始化变量读取字符串a,记录长度 读取空行读取字符串b,记录长度推演二维表 输出结果,