后缀自动机的直观理解

后缀自动机(SAM)

搜了网上,多介绍应用,[3]算是一个比严格的定义性描述,并给出了证明。但是这个证明我并未看懂,下面综合一些资料给一些个人的直观但不失严谨的理解。

给定一个串A的后缀自动机是一个有限状态自动机(DFA),它能够且仅能够接受A的后缀,并且我们要求它的状态数最少。

设n=|A|, 状态数:st=[n+1,2n-1], 边数:eg=[n,3n-4]。构造:空间复杂度:26*st, 时间复杂度O(3n)。查询:O(|q|);

可以看出,我们有可能把26*st优化到3*st的。

先上图,有个直观认识:

<fig1>

这是表示串A="abaaaba"的后缀自动机,红色的S表示开始状态,红色的表示接受状态,黑色的表示非接受状态。从这个图可以看出,某个节点可以是多个节点的儿子,节省了状态空间。

定义:

状态p :=R(u)的等价类。其中R(u) := {u在A中出现位置右端点}。

比如上图中状态7识别两个后缀,满足R("aba") = R("ba")={3,7}。p称为接受状态是指自动机识别了一个从初始状态到p所表示的子串是A的后缀。

状态转移(p,c,q)表示状态p通过字符c转移到状态q。

后缀函数S(A,u):= u的最长后缀v,满足v不在u等价类中。

u=A时称为后缀链接,[3]引理1.5说S(A,A)=A中至少出现两次的最长后缀。

记最后一个加入的状态为last,则last,S(A,last), S(A,S(A,last),...组成接受状态构成的后缀路径SP。注意的是其他非接受状态的后缀链接也可以指向某个接受状态。 后缀链接指向上一个可以接受后缀的结点

 

长度函数L(A,p):= 初始状态到p的最长路径长度。即从根节点走到该节点,最多需要多少步。

下面我们考察状态机A增加一个字符x后,A的状态变化。

令z是A出现的且是Ax的最长后缀, zp是A中最长子串且zp,z属于A的同一等价类。

推论2.3.12说,如果x不在A中,则A的等价类在Ax中不变。(I)

推论2.3.11说,如果z=zp, 则A的等价类在Ax中不变。(II)

定理2.3.10说,如果z!=zp,则A中与z的等价类在Ax要改成zp。(III)

例子,  如下图,A="ccccbbccc", x=‘d‘对应(I),S(Ax,Ax)="";

后缀链接没有必要显示画出来,因为观察SP,就知道是9->3->2->1->0。

x=‘c‘对应(II),z="cccc", R(z)={4}, zp=z, S(A,A)="ccc", S(Ax,Ax)=z;

x=‘b‘对应(III),z="cccb",R(z)={5}=R(zp),zp="ccccb", S(Ax,Ax)=z。

<fig2>

增量构造法:

设当前串为A,加入字符为x。

令p为R(A)={L(A)}对应的状态, 新节点np为R(Ax)={L(A)+1}对应的状态。

np显然应该是Ax的一个接受状态,np应该挂接到哪个位置呢?

为了节省状态空间,我们应该尽可能公用公共前缀,且尽可能让图宽以降低路径长度。

因此从last开始,沿着后缀链接跳,直到跳到第一个有x出边的v节点。

对p所有没有x出边的后缀链接v=S(A,p), trans(v,x)=np, 找第一个有x出边的v,令q=trans(v,x),

1. 如果L(q) = L(p)+1, p-->q只有由x可达,我们只需把q作为接受状态,到q的路径都是Ax的后缀。

2. 如果L(q)!=L(p)+1, p-->q就可能有其他若干字符可达,虚拟一个节点nq表示1的情形,把q,np的S都指向nq。

核心代码只有20行(估计后缀树代码量要大很多,这也是SAM的优势之一):

    void add(int x)
    {
        State p = last, np = new State();
        np.val = last.val + 1;
        for(; (p != null) && (p.go[x] == null); p = p.fa)
            p.go[x] = np;
        if(null == p){
            np.fa = root;
        }else{
            State q = p.go[x];
            if(q.val == p.val + 1){
                np.fa = q; /*S(np)=q*/
            }else{
                State nq = new State();
                nq.copy(q); /*trans(nq,*)=trans(q,*)*/
                nq.val = p.val + 1;
                q.fa = np.fa = nq;
                for(; (p != null) && (p.go[x] == q); p = p.fa)
                    p.go[x] = nq;
            }
        }
        last = np;
    }

Todo

我发现后缀链接很像KMP的向后跳。整理代码用模式串构造SAM,下周整理出来。

Ref

[1] 加速2,3 https://www.cs.duke.edu/courses/fall12/compsci260/resources/suffix.trees.in.detail.pdf

[2]后缀指针构造

http://marknelson.us/1996/08/01/suffix-trees

[3] Algebraic Combinatorics On Words.pdf

http://www.ctzsm.com/%E5%90%8E%E7%BC%80%E8%87%AA%E5%8A%A8%E6%9C%BA%E6%8A%A5%E5%91%8A/

后缀自动机的直观理解

时间: 2024-11-02 02:35:28

后缀自动机的直观理解的相关文章

bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 对广义后缀自动机的一些理解

先说一下对后缀自动机的理解,主要是对构造过程的理解. 构造中,我们已经得到了前L个字符的后缀自动机,现在我们要得到L+1个字符的后缀自动机,什么需要改变呢? 首先,子串$[0,L+1)$对应的状态不存在,应当建立一个状态来表示这个串,显然,这个状态(np)的right集合是{L+1},max=L+1. 现在新建立了一个状态,我们还有两件事要干:找出能转移到这个状态的状态,建立链接:确定这个状态的min,即找到它在parent树上的父亲. 能转移到$np$的状态显然都是right集合包含L的状态,

浅谈对后缀自动机的一点理解

后缀自动机入门详解及模板 后缀自动机 自动机 要想了解后缀自动机,首先得了解自动机. 例如AC自动机,AC自动机可以识别一个字符串为其所匹配的前缀. 而我们今天所介绍的后缀自动机则是识别一个字符串为自动机串的子串. 在接下来的描述中为了方便,简称\(SAM\). 暴力实现 我们知道字典树有着优良的时空复杂度,并且可以支持识别一个字符串的前缀. 如果我们将串中的所有后缀插入进字典树,那么就可以实现这个自动机的功能. 不过,由于忽视了后缀的这个性质,总点数高达\(O(n^2)\). 即使如此,字典树

关于后缀自动机的一些理解

咕咕咕了好久的东西,以前只是粗糙的背个板子之类的,并未对parent树有什么深刻的理解 clj姐姐tql,这么神仙的东西是怎么想出来的啊 个人认为有以下几点是难以理解的: 一.right集合的定义: right集合就是指某一子串在原串当中出现的所有的位置的集合,也在某位大佬博客中叫做endpos集合: 二.right集合(endpos集合)相同的我们称为endpos等价类(重点理解) 三.对于任意两个endpos集合中,那么必然为其中一个为另一个的子串,或者两者绝无交集 四.endpos的等价类

后缀自动机详解 -----转载

转载于:http://blog.csdn.net/qq_35649707/article/details/66473069 原论文(俄文)地址:suffix_automata 后缀自动机 后缀自动机(单词的有向无环图)——是一种强有力的数据结构,让你能够解决许多字符串问题. 例如,使用后缀自动机可以在某一字符串中搜索另一字符串的所有出现位置,或者计算不同子串的个数——这都能在线性 时间内解决. 直觉上,后缀自动机可以被理解为所有子串的简明信息.一个重要的事实是,后缀自动机以压缩后的形式包含了一个

『后缀自动机入门 SuffixAutomaton』

本文的图片材料多数来自\(\mathrm{hihocoder}\)中详尽的\(SAM\)介绍,文字总结为原创内容. 确定性有限状态自动机 DFA 首先我们要定义确定性有限状态自动机\(\mathrm{DFA}\),一个有限状态自动机可以用一个五元组\((\mathrm{S},\Sigma,\mathrm{st},\mathrm{end},\delta)\)表示,他们的含义如下: \(1.\) \(\mathrm{S}\) 代表自动机的状态集 \(2.\) \(\Sigma\) 代表字符集,也称字

后缀自动机的一点点理解

后缀自动机的一点点理解 前言 最近心血来潮,想学学SAM,于是花了一晚上+一上午 勉强打了出来(但是还是不理解) 虽说张口就讲我做不到 但是一些其他的东西还是有所感触的 索性,乱口胡点东西,谢谢关于SAM的一些简单的理解 资料 丽洁姐WC PPT hihocoder上的后缀自动机 一些概念 这些概念都不读懂,接下来真的是步履维艰 本来我们要的是一个能够处理所有后缀的数据结构 但是我们发现,如果对于每一个后缀都要插入进Trie树 空间复杂度完全背不动(\(O(n^2)\)级别) 于是,后缀自动机出

【BZOJ3926】[Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机

[BZOJ3926][Zjoi2015]诸神眷顾的幻想乡 Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看.幽香当然也非常高兴啦. 这时幽香发现了一件非常有趣的事情,太阳花田有n块空地.在过去,幽香为了方便,在这n块空地之间修建了n-1条边将它们连通起来.也就是说,这n块空地形成了一个树的结构. 有n个粉丝们来到了太阳花田上.为了表达对幽香生日的祝

[转]后缀自动机

原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了... 笔者自己的话会用楷体表示出来...[说不定能帮助大家理解,但是可能也破坏了大家的自主理解力?所以...看不懂的话再来看好咯...] 常用的字符串处理工具: 1.       整词索引:排序+二分:Hash表.可以解决整词匹配,但不支持前缀搜索:Hash表在模式串定长的情况下可以用RK解决多模式

hdu 4622 Reincarnation(后缀数组|后缀自动机|KMP)

Reincarnation Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 2138    Accepted Submission(s): 732 Problem Description Now you are back,and have a task to do: Given you a string s consist of lo