码迷,mamicode.com
首页 > 其他好文 > 详细

KMP与扩展KMP初探

时间:2014-08-17 12:55:12      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   for   ar   div   代码   log   

KMP

KMP算法主要用于字符串匹配中的单串匹配

next函数:表示当前字符失配时,应从模式串的第几位开始匹配(越大越好)。即模式串的前缀与以t[i]为结尾的后缀的最长相同部分的长度。

代码如下(pascal)

var
        s,t:string;
        next,ans:array[0..100] of longint;
        i,j:longint;
begin
        readln(s);
        readln(t);
        next[1]:=0;

        {构造next}
        j:=0;
        for i:=2 to length(t) do
        begin
                while (j>0)and(t[j+1]<>t[i]) do j:=next[j]; {失配}
                if t[j+1]=t[i] then j:=j+1;
                next[i]:=j;
        end;

        {KMP主程序}
        j:=0;
        for i:=1 to length(s) do
        begin
                while (j>0)and(t[j+1]<>s[i]) do j:=next[j]; {失配}
                if t[j+1]=s[i] then j:=j+1;
                if j=length(t) then                         {找到匹配}
                begin
                        inc(ans[0]);
                        ans[ans[0]]:=i-length(t)+1;
                        j:=next[j];
                end;
        end;
        for i:=0 to ans[0] do
         writeln(ans[i]);
end.

扩展KMP

顾名思义就是KMP算法的扩展,其可以求出以s[i]为开始的字符串,与t的最长公共前缀。

扩展KMP的next函数:表示以t[i]为开始的字符串,与t的最长公共前缀的长度。

扩展KMP的extend函数:表示以s[i]为开始的字符串,与t的最长公共前缀的长度。

代码如下(pascal)

var
        s,t:ansistring;
        i,j,k,p,l,n,m:longint;
        next,extened:array[0..1000] of longint;
begin
        readln(s);
        readln(t);
        n:=length(s);
        m:=length(t);
        s:=s+@;    {防越界}
        t:=t+#;    {防越界}

        {构造next}
        j:=0;
        while T[1+j]=T[2+j] do inc(j);
        next[2]:=j;
        k:=2;
        for i:=3 to m do
        begin
                p:=k+next[k]-1;        {p为最远的已比较过的点}
                l:=next[i-k+1];        {l为t与t[i-k+1..m]的LCP}
                if l+i-1<p then next[i]:=l
                else begin
                        if p-i+1>0 then j:=p-i+1 else j:=0;
                        while T[i+j]=T[1+j] do inc(j);
                        next[i]:=j;
                        k:=i;          {更新k}
                end;
        end;

        {Extened_KMP主程序}
        j:=0;
        while T[1+j]=S[1+j] do inc(j);
        extened[1]:=j;
        k:=1;
        for i:=2 to n do
        begin
                p:=k+extened[k]-1;     {p为最远的已比较过的点}
                l:=next[i-k+1];        {l为t与t[i-k+1..m]的LCP}
                if l+i-1<p then extened[i]:=l
                else begin
                        if p-i+1>0 then j:=p-i+1 else j:=0;
                        while S[i+j]=T[1+j] do inc(j);
                        extened[i]:=j;
                        k:=i;          {更新k}
                end;
        end;
        for i:=1 to n do
         writeln(extened[i]);
end.

KMP与扩展KMP初探,布布扣,bubuko.com

KMP与扩展KMP初探

标签:style   blog   color   for   ar   div   代码   log   

原文地址:http://www.cnblogs.com/zhu8655/p/3917598.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!