DP:编辑距离
字符串是数据结构和计算机语言里很重要的数据类型,在计算机语言中,对于字符串我们有很多的操作定义,因此我们可以对字符串进行很多复杂的运算和操作。实际上,所有复杂的字符串操作都是由字符串的基本操作组成。例如,把子串a替换为子串b,就是用查找、删除和插入这三个基本操作实现的。因此,在复杂字符串操作的编程中,为了提高程序中字符操作的速度,我们就应该用最少的基本操作完成复杂操作。
在这里,假设字符串的基本操作仅为:删除一个字符、插入一个字符和将一个字符修改成另一个字符这三种操作。
我们把进行了一次上述三种操作的任意一种操作称为进行了一步字符基本操作。
下面我们定义两个字符串的编辑距离:对于两个字符串a和b,通过上述的基本操作,我们可以把a变成b或b变成a;那么,把字符串a变成字符串b需要的最少基本字符操作步数称为字符串a和字符串b的编辑距离。
例如,如a=“ABC”,b=“CBCD”,则a与b的编辑距离为2。
你的任务就是:编一个最快的程序来计算任意两个字符串的编辑距离。
输入数据:
第1行为字符串a;第2行为字符串b。注:字符串的长度不大于1000,字符串中的字符全为大写字母。
输出数据:
编辑距离。
样例
输入文件名:edit.in
ABC
CBCD
输入文件名:edit.out
2
题意:操作方法有三种:删除、插入、修改;
问:用最少的步骤将字符串①转化为字符串②
输出最少的步骤数
思路:一开始看到这道题,觉得搜索的方法很难做出来{因为不知道向什么方向进行操作}
视频(*诸城本*)讲的是动态规划的方法,f[i,j]设为字符串①{s1}的前i位转换为字符串②{s2}的前j位所需要的最少操作步骤:如果s1[o]=s2[j],那么f[i,j]=f[i-1,j-1]{不需操作},如果s1[i]<>s2[j],那么分为三种情况,删除f[i,j]=f[i-1,j]+1;插入f[i,j]=f[i,j-1]+1;转化f[i,j]=f[i-1,j-1]+1;
F[i,j]=/f[i-1,j-1] s1[i]=s2[j]
\min{f[i-1,j] s1[i]<>s2[j]
F[i,j-1]
F[i-1,j-1]}+1
代码:
var a,b:ansistring;
f:array[0..4000,0..4000]of integer;
n,m:longint;
min:longint;
i,j,k:longint;
begin readln(a);
readln(b);
n:=length(a);
m:=length(b);
fillchar(f,sizeof(f),0);
for i:=0 to n do
f[i,0]:=i;
for j:=0 to m do
f[0,j]:=j;
for i:=1 to n do
for j:=1 to m do
if a[i]=b[j]
then f[i,j]:=f[i-1,j-1]
else begin min:=maxlongint;
if f[i-1,j]<min
then min:=f[i-1,j];
if f[i,j-1]<min
then min:=f[i,j-1];
if f[i-1,j-1]<min
then min:=f[i-1,j-1];
f[i,j]:=min+1;
end;
write(f[n,m]);
end.