题目大意:求两个字符串的公共子串。
分析:
模板题,将两个字符串接起来用不会出现的字符分割,然后求分属两个字符串的相邻后缀lcp的最大值即可。
代码:
program work; type arr=array[0..20001]of longint; var sa,rank,b,tmp,lcp:arr; n,i,m,l,u,ans,t:longint; s,s1,s2:ansistring; ch:char; function compare(i,j,k:longint):longint; var ri,rj:longint; begin if rank[i]<>rank[j] then exit(ord(rank[i]<rank[j])) else begin if i+k<=n then ri:=rank[i+k] else ri:=-1; if j+k<=n then rj:=rank[j+k] else rj:=-1; exit(ord(ri<rj)); end; end; procedure qsort(l,h,k:longint; var a:arr); var i,j,t,m:longint; begin i:=l; j:=h; m:=a[(i+j) div 2]; repeat while compare(a[i],m,k)=1 do inc(i); while compare(m,a[j],k)=1 do dec(j); if i<=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); end; until i>j; if i<h then qsort(i,h,k,a); if j>l then qsort(l,j,k,a); end; procedure work_sa(s:ansistring; var sa:arr); var k,i:longint; begin for i:=1 to n do begin sa[i]:=i; rank[i]:=ord(s[i]); end; k:=1; while k<=n do begin qsort(1,n,k,sa); tmp[sa[1]]:=1; for i:=2 to n do tmp[sa[i]]:=tmp[sa[i-1]]+compare(sa[i-1],sa[i],k); rank:=tmp; k:=k*2; end; end; function max(x,y:longint):longint; begin if x>y then max:=x else max:=y; end; procedure work_lcp(s:ansistring;var sa,lcp:arr); var i,j,h:longint; begin for i:=1 to n do rank[sa[i]]:=i; h:=0; lcp[1]:=0; sa[0]:=0;rank[0]:=0; for i:=1 to n do begin j:=sa[rank[i]-1]; if h>0 then dec(h); while (i+h<=n)and(j+h<=n) do begin if s[i+h]<>s[j+h] then break; inc(h); end; lcp[rank[i]-1]:=h; end; end; begin readln(u); for l:=1 to u do begin readln(s1); readln(s2); s:=s1+‘@‘+s2; t:=length(s1); n:=length(s); work_sa(s,sa); work_lcp(s,sa,lcp); ans:=0; for i:=1 to n-1 do begin if ((sa[i]<=t)and(sa[i+1]>=t+2))or((sa[i+1]<=t)and(sa[i]>=t+2)) then ans:=max(ans,lcp[i]); end; writeln(‘Nejdelsi spolecny retezec ma delku ‘,ans,‘.‘); end; end.
时间: 2024-10-09 01:56:24