好了下午刚学KMP~
于是现在复习一下~
AB两串,求B串在A串中出现的次数~
其实就是一个暴力的匹配,加上记忆一下要回到哪里;
两个指针,i在A上,j在B上,表示A[I-J+1..I] 和 B[1..J]相同
设fail[j]表示在第j项匹配成功,,但下一项失败j要回去到哪一项开始
即求一个k,使s[1..k]=s[j-k+1..j] 且k最大
可以依靠原有的基础上求解
if s[fail[j-1]+1]=s[j] then fail[j]:=fail[j-1]+1;
否则呢?if s[fail[fail[j-1]]+1]=s[j] then fail[j]:=fail[fail[j-1]]+1;
为什么呢?
可以看到
由fail的定义可得,s[fail[fail[j-1]]]之前的字符串和s[j]之前相同数量的字符串是一样的
那么又相等就是原来的+1了
于是现在复习一下~
AB两串,求B串在A串中出现的次数~
其实就是一个暴力的匹配,加上记忆一下要回到哪里;
两个指针,i在A上,j在B上,表示A[I-J+1..I] 和 B[1..J]相同
设fail[j]表示在第j项匹配成功,,但下一项失败j要回去到哪一项开始
即求一个k,使s[1..k]=s[j-k+1..j] 且k最大
可以依靠原有的基础上求解
if s[fail[j-1]+1]=s[j] then fail[j]:=fail[j-1]+1;
否则呢?if s[fail[fail[j-1]]+1]=s[j] then fail[j]:=fail[fail[j-1]]+1;
为什么呢?
可以看到
由fail的定义可得,s[fail[fail[j-1]]]之前的字符串和s[j]之前相同数量的字符串是一样的
那么又相等就是原来的+1了
Code:
function KMP(a,b:string):longint;
var i,j,ans:longint;
begin
fail[1]:=0;
j:=0;
ans:0;
for i:=2 to length(b) do
begin
while (j>0) and (b[j+1]<>b[i]) do j:=fail[j];
if b[j+1]=b[i] then inc(j);
fail[i]:=j;
end;
j:=0;
for i:=1 to length(a) do
begin
while (j>0) and (b[j+1]<>a[i]) do j:=fail[j];
if b[j+1]=b[i] then inc(j);
if j=length(b) then begin
inc(ans);
j:=f[j];
end;
end;
exit(Ans);
end;