Cod sursa(job #1510544)

Utilizator ili226Vlad Ilie ili226 Data 25 octombrie 2015 12:03:04
Problema Aho-Corasick Scor 10
Compilator fpc Status done
Runda Arhiva educationala Marime 2.62 kb
{ val(c)-val('a')+1 }
type cuv=array[1..10000]of byte;
     nd=^nod;
     nod=record
          val:byte;
          fault:nd;
          next:array[1..26]of nd;
         end;
var s,potrivire:array[1..1000003]of byte;
    x:cuv;
    t,n,i,lx:byte;
    c:char;
    f:text;
    ap:nd;
    p,pp:nd;
    ltot:longint;
    ies:boolean;
procedure adauga(x:cuv;l,nr:byte;var p:nd;j:byte);
var pp:nd;
    k:byte;
begin
if p{^.next[x[j]]}=nil then
 begin
  new(pp);
  pp^.val:=0;
  pp^.fault:=nil;
  for k:=1 to 26 do
   pp^.next[k]:=nil;
  p{^.next[x[j]]}:=pp;
  if j<l then adauga(x,l,nr,p^.next[x[j+1]],j+1)
         else p^.val:=nr;
 end
                     else
 begin
  if j<l then adauga(x,l,nr,p^.next[x[j+1]],j+1)
         else p^.val:=nr;
 end;
end;

procedure bfs;
var x,y:longint;
    i:byte;
    coada:array[1..100{0003}]of nd;
    f:nd;
begin
x:=0;y:=1;
coada[y]:=ap;
repeat
inc(x);
 for i:=1 to 26 do
  if coada[x]^.next[i]<>nil then
   begin
    inc(y);
    coada[y]:=coada[x]^.next[i];
    f:=coada[x]^.fault;
    while (f^.next[i]=nil)and(f<>ap)do
     begin
      f:=f^.fault;
     end;
    if f=ap then
     if f^.next[i]=nil then f:=ap
                       else f:=f^.next[i]
            else
     f:=f^.next[i];
    if coada[x]=ap then f:=ap;
    coada[y]^.fault:=f;
   end;
until {x=ltot}x=y;
end;

begin
new(p);
p^.val:=0;
p^.fault:=p;
for i:=1 to 26 do
 p^.next[i]:=nil;
ap:=p;
assign(f,'ahocorasick.in');
reset(f);
n:=0;
while not(eoln(f))do
 begin
  inc(n);
  read(f,c);
  s[n]:=ord(c)-ord('a')+1;
 end;
readln(f);
readln(f,t); ltot:=0;
for i:=1 to t do
 begin
 lx:=0;
  while not(eoln(f))do
   begin
    inc(lx);
    read(f,c);
    x[lx]:=ord(c)-ord('a')+1;
   end;
  inc(ltot,lx);
  adauga(x,lx,i,ap^.next[x[1]],1);
  readln(f);
 end;
close(f);
bfs;
p:=ap;
for i:=1 to n do
 begin
  {if p^.val<>0 then
   inc(potrivire[p^.val]);
  pp:=p^.fault;
  while pp<>ap do
   begin
    if pp^.val<>0 then
     inc(potrivire[pp^.val]);
    pp:=pp^.fault;
   end;}
  ies:=false;
  if i<=n then
  if p^.next[s[i]]<>nil
   then
    begin p:=p^.next[s[i]];
    end
   else
    repeat
     p:=p^.fault;
     if p^.next[s[i]]<>nil then
      begin
       ies:=true;
       p:=p^.next[s[i]];
      end;
     if (not ies)and(p=ap)then ies:=true;
    until ies;

   if p^.val<>0 then
   inc(potrivire[p^.val]);
  pp:=p^.fault;
  while pp<>ap do
   begin
    if pp^.val<>0 then
     inc(potrivire[pp^.val]);
    pp:=pp^.fault;
   end;
 end;
assign(f,'ahocorasick.out');
rewrite(f);
for i:=1 to t do
 writeln(f,potrivire[i]);
close(f);
end.