后缀自动机
2015-06-10 08:44
232 查看
http://blog.sina.com.cn/s/blog_7812e98601012cim.html //后缀自动机建立的详细介绍
http://www.tuicool.com/articles/Mjuu2y //后缀自动机学习指南(习题列表)
http://www.tuicool.com/articles/Mjuu2y //后缀自动机学习指南(习题列表)
const maxn=10008; var a,f,rig:array[0..maxn] of longint; nt:array[0..maxn,'a'..'z'] of longint; last,sum,i:longint; s:ansistring; eg:array[0..maxn*2] of record nt,v:longint; end; lt:array[0..maxn] of longint; el:longint; procedure SAM_init; begin fillchar(f,sizeof(f),255); fillchar(nt,sizeof(nt),255); fillchar(a,sizeof(a),0); last:=0; sum:=0; end; procedure SAM_ins(ch:char); var next,p,np,q,nq:longint; begin //next:=nt[last][ch]; 添加多个串使用 //if (next<>-1) and (f[last+1]<>f[next]) then begin last:=next; exit; end; inc(sum); p:=last; np:=sum; a[np]:=a[p]+1; last:=np; rig[np]:=1; while (p<>-1) and (nt[p][ch]=-1) do begin nt[p][ch]:=np; p:=f[p]; end; if p=-1 then f[np]:=0 else begin q:=nt[p][ch]; if a[p]+1=a[q] then f[np]:=q else begin inc(sum); nq:=sum; a[nq]:=a[p]+1; nt[nq]:=nt[q]; f[nq]:=f[q]; f[q]:=nq; f[np]:=nq; while (p<>-1) and (nt[p][ch]=q) do begin nt[p][ch]:=nq; p:=f[p]; end; end; end; end; procedure SAM_visit; //遍历所有后缀 var x:longint; v:array[0..maxn] of boolean; procedure dfs(now:longint; t:string); var c:char; begin if v[now] then writeln(t); for c:='a' to 'z' do if nt[now][c]<>-1 then dfs(nt[now][c],t+c); end; begin x:=last; while x<>0 do begin v[x]:=true; x:=f[x]; end; dfs(0,''); end; procedure SAM_visit1;//遍历所有子串 并统计次数 procedure dfs(now:longint; t:string); var c:char; begin if now<>0 then writeln(t,' ',rig[now]); for c:='a' to 'z' do if nt[now][c]<>-1 then dfs(nt[now][c],t+c); end; begin dfs(0,''); end; function SAM_calc:longint; //本质不同的串 var i,cnt:longint; begin cnt:=0; for i:=1 to sum do cnt:=cnt+a[i]-a[f[i]]; exit(cnt); end; procedure SAM_rig; procedure dfs(u:longint); var i:longint; begin i:=lt[u]; while i<>0 do begin dfs(eg[i].v); rig[u]:=rig[u]+rig[eg[i].v]; i:=eg[i].nt; end; end; procedure add(u,v:longint); begin inc(el); eg[el].v:=v; eg[el].nt:=lt[u]; lt[u]:=el; end; begin el:=0; fillchar(lt,sizeof(lt),0); for i:=1 to sum do add(f[i],i); dfs(0); end; begin SAM_init; readln(s); for i:=1 to length(s) do SAM_ins(s[i]); SAM_rig; SAM_visit1; end.
相关文章推荐
- 十三周——输入输出流——项目三 电子词典解决版——输出汉字乱码的处理
- 【软测试】计算机硬件
- NDK环境配置
- Mysql 数据类型与java中的数据类型对照表
- 2015、6、10
- 第十四周程序阅读 控制符控制输出格式
- 第十四周项目1-小玩文件(1)
- Struts 2 学习笔记:Struts 2 的命名空间(namespace)的用法和作用
- 第14周项目 例4.2
- 第十四周项目一——小玩文件(2)
- .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
- 中国第二代身份证验证js代码
- 第十四周项目:小玩文件(2)
- .Net 转战 Android 4.4 日常笔记(3)--目录结构分析
- 【render】partial及其局部变量
- 第14周项目1 - 小玩文件(3)
- openstack kilo keystone token问题及性能优化
- struts2学习笔记(2)---Action中访问ServletAPI获取Map类型的Servlet元素
- 第十四周 阅读项目 标准输入输出流
- sgu 205