poj 2752 Seek the Name, Seek the Fame KMP算法

题目:给出一个字符串s,求有多少个s的子串既是s的前缀也是s的后缀。

分析:若真正理解了KMP算法,这题就变得非常简单了。首先,next[j]=max{k|1<=k<=j且's1s2...sk'='sj-k+1...sj'},若无满足条件的k则为0.有next数组的定义容易的出s的前next[len](len为s长度)个字符组成的子串一定满足题目要求,这样就找到了出字符串本身最长的满足条件的子串。同理,可以找到所有的满足条件的子串的长度。

下面附程序:

var
  a:ansistring;
  len,i,s1:longint;
  s,next:array[0..400000] of longint;

procedure get;
var
  i,j:longint;
begin
  next[1]:=0;
  next[0]:=-1;
  i:=2;
  j:=0;
  while i<=len do
    if (j=-1)or(a[i]=a[j+1])
      then begin
             inc(j);
             next[i]:=j;
             inc(i);
           end
      else j:=next[j];
end;

begin
  while not eof do
  begin
    readln(a);
    len:=length(a);
    get;
    s1:=1;
    s[1]:=len;
    i:=len;
    while next[i]>0 do
    begin
      inc(s1);
      s[s1]:=next[i];
      i:=next[i];
    end;
    for i:=s1 downto 1 do
      write(s[i],' ');
    writeln;
  end;
end.


你可能感兴趣的:(poj 2752 Seek the Name, Seek the Fame KMP算法)