编辑距离(edit.pas/c/cpp)
字符串是一个基本却很常用的数据类型,所有研究它的性质就显得尤为重要。对于一个
字符串有三种基本操作:
[+]插入一个字符
[+]删除一个字符
[+]修改一个字符
两个字符串的编辑距离是指,将一个字符串变为另一个字符串所需要的最小基本操作
数。例如两个字符串”abc”和”dbcd”,它们的编辑距离是2,因为将”abc”变为”dbcb”
只需要2步:把’a’修改成’d’,再在字符串末尾添加一个字符’b’。
现在你需要解决的问题是:给定两个字符串,求出它们的编辑距离。
输入数据
两行两个字符串,所有字符均为大写字母。
输出数据
字符串是一个基本却很常用的数据类型,所有研究它的性质就显得尤为重要。对于一个
字符串有三种基本操作:
[+]插入一个字符
[+]删除一个字符
[+]修改一个字符
两个字符串的编辑距离是指,将一个字符串变为另一个字符串所需要的最小基本操作
数。例如两个字符串”abc”和”dbcd”,它们的编辑距离是2,因为将”abc”变为”dbcb”
只需要2步:把’a’修改成’d’,再在字符串末尾添加一个字符’b’。
现在你需要解决的问题是:给定两个字符串,求出它们的编辑距离。
输入数据
两行两个字符串,所有字符均为大写字母。
输出数据
两个字符串的编辑距离
样例输入
ABCDEFG
CCDEF
输出
3
数据范围
对于所有的数据,满足两字符串的长度都不超过10000
对于90%的数据,字符串长度不超过6000,时间限制2秒
对于剩下10%的数据,长度10000,时间限制5秒
-------------------------------------------------------------------------------------------------------------------
DP,状态转移就不提了,关键是如果开10000*10000的数组直接就会爆掉,必须要用滚动数组技术。
-------------------------------------------------------------------------------------------------------------------
代码:
var
s1,s2:ansistring;
f:array[0..1,0..10000] of integer;
m,n:longint;
function min(a,b,c:longint):longint;
begin
min:=a;
if b<min then min:=b;
if c<min then min:=c;
end;
procedure main;
var
i,j:longint;
begin
readln(s1); m:=length(s1);
readln(s2); n:=length(s2);
for j:=1 to n do f[0,j]:=j; f[0,0]:=0;
for i:=1 to m do begin
f[i mod 2,0]:=i;
for j:=1 to n do begin
f[i mod 2,j]:=min(f[(i+1)mod 2,j],f[i mod 2,j-1],f[(i+1)mod 2,j-1])+1;
if (s1[i]=s2[j])and(f[(i+1)mod 2,j-1]<f[i mod 2,j])then f[i mod 2,j]:=f[(i+1) mod 2,j-1];
end;
end;
write(f[m mod 2,n]);
end;
begin
assign(input,'edit.in'); reset(input);
assign(output,'edit.out'); rewrite(output);
main;
close(input); close(output);
end.