小さなノートを学ぶサフィックス自動機

序文

正直に言うと、私はいつも少しあいまいな感じ......学ぶために何回か分からないし、合計するノートを書きます。


サフィックスオートマトンをしているのですか?

まず第一に、あなたは「自動機」の概念を知っておく必要があります。

有限ステートマシンは、文字列を識別することです。
自動機械のように\(\) それは文字列を認識した場合、\(S \)を、続いてみましょう\((S)は\ = TRUE) または\((S)は、偽=
\) 5のオートマトンをパーツ- \
(アルファ\) 文字セット、\(状態\) 状態の集合\(のinit \)初期状態、:\(エンド\) 完成状態のセット、\(トランス\) 遷移状態機能。

そして、文字列\(S \)演技「サフィックスオートマトンは」識別\(S \)すべてのサブ文字列の
だから、何を使用ですか?
把握することができます\(S \)などように、「ストリングの異なる性質の数」、「最小の文字列表現」となどの問題に対処するためのサブストリング間の関係のいくつかを。
そしてので、サフィックスオートマトンは、いくつかの特殊な性質を持っていますが、また多くの特別な問題を解決します。


具体的には、サフィックスオートマトンをしているのですか?

有向非巡回グラフ(で\(DAG \)に示されている)\(S \)すべてのサブストリングの。

\(DAG \)は、いくつかのプロパティがあります。

  1. 点源、シンク複数の、通常複数のノードがあります。一つのノードから別のノードへの各点は、文字のエッジです。
  2. すべての文字を順次形成するように接続されたシンクのいずれかの道路上の任意の点までのソースから来る\(S \)サフィックスのを。
  3. すべての文字が一緒に接続された任意の道路ターン上の任意のノードにソース・ポイントから来る\(S \)ストリングのを。
  4. \(S \)「3」サブストリングを介して利用可能なすべての方法から出て、点光源、異なる経路によって形成された異なるサブストリングから出発。

シンプルで、粗実現

内蔵\(トライ\)木、\(S \)を挿入するために、すべてのサフィックスのを。
時間と空間はただ......です\(O(N ^ 2) \) 怪我を買う余裕はない傷害のレベルは余裕がありません。

だから我々はできるだけ状態の数と自動転送機の数を減らす必要があります。
\(そう\) "サフィックスオートマトン" \(SAM \)


一部のプロパティは、サブストリング

\ -の概念を導入(\ endposの)

文字列\(X \) A \(endposの\)である\(X \)文字列中の(S \)\収集が終了位置に発生します。
例えば、\(S = aababba \)、\ (AB&X = \) 次いで\(endposの(X)= { 3,5} \)

ため\(endposの\)同じ2つの文字列、明らかに\(S \) 追跡することができる文字は、転送のすなわち同じ側に同じです。\(endposの\)同値クラスと呼ばれる同じ文字列。したいこと(SAM \)は\彼らは同じノードを使用していることが示されました。

いくつかのプロパティは、(明らかに比較、許可していません):
任意の二つのサブ文字列では\(S1 \)、\ (S2が\) 設定したいことがあり、\(長さ(S1)<長さ (S2)\)

  1. \(S1 \)\(S2 \)接尾辞\(\ Leftrightarrow \) \(endposの(S1)\ supseteq endposの(S2)\)
  2. \(S1が\)されていない\(S2 \)接尾辞\(\ Leftrightarrow \) \(endposの(S1)\ CAP endposの(S2)= \ emptySet \)

換言すれば、\(S1 \)\(S2 \)\(endposの\)互いに素、または別に含まれるいずれか2つだけの関係、。


SAM組成

ノード

既に述べたように、各ノードが表す\(endposの\)すべての文字列を同じ。
実際には、これらの異なるサブストリングは、ソースノードから文字列を表す異なる経路のすべてに形成されています。

\(endposの\)ライセンスの性質上、すべての文字列は、各ノードが互いに連続接尾語との関係を表している
ような、\(S = aababba \)\(endposのを7} = {\)サブストリングのと\( aababba、ababba、babba、アバ、 BBAの\)

各ノードが提供される\(U \)最長ストリングが表される\(MAX(U)\) 最短のサブストリング\(MIN(U)\)

非環式のワード転送と図辺

\(U \)する(V \)を\文字た\(C \)は転送端で、示して\(U \)文字との文字列で表される\(C \)文字列を形成した後、新たに利用可能に(\ V \)代表。
ことに注意してください。この図はワードである\(DAG \)は必ずしもない、(V \)を\して、すべてのサブ文字列の代わりに、\(U \)への転送

図前述の特性は、言葉を述べ、その後、彼の[]の後ろに固執
任意の道路上の任意のノードに移動全ての文字のソースから形成するために、最大接続回し\(S \)をサブの。
\(S \)すべてのサブストリングのは、このように出てくることができ、ソースから、異なるサブストリングは、異なる経路によって形成されます。

サフィックスとプレフィックスツリーリンク

「ノード」に「は、各ノードはすべての文字列が互いに連続接尾語関係である表し」、前記
想定できる\(U \)文字列のセットはサブによって表すことができる\(サブストリング(U)\)は、任意の(\サブストリングにおけるX- \(U)\) 満足\(X \)がされている\(MAX(U)\)サフィックス。

依然として例えば、上で引用\(S = aababba \)\(endposの= {7} \)を持つストリングの\(aababba、ababba、babba、
アバ、BBAの\) 5つのサブストリングのみ\(S \ )サフィックスの一部、ならびに\(BAの\)(\ (endposの= {4,7} \) および\(\)(\ (endposの= {1,2,4,7}は\)
提供表す\(endposの= {7} \ ) ノードである(X \)を\表し\(endposのを= {4,7} \ ) ノードである(Y \)を\表し、\(endposの= {1,2、 4,7} \)ノードであるの\(Z \)
その後もサフィックスリンク(または\(PA \)エッジ)\(X \ Yに対して、Y \ Zが\に)

見つけることができる、\(U \)接尾辞リンクはにつながる(\ V)\と場合にのみ場合、(|分(U)| \ 1 \ = | |マックス(V)) と(\ V)\表さ全体の文字列です\(U \)サフィックス文字列表現。サフィックスは、この木が呼び出された各ポイントに対して1つだけのリンク、ツリーを形成することであるプレフィックスツリー(または\(親\)木)

いくつかの特性:
サフィックスジャンプフォワードリンクに沿った各点について、ノードを介して長さが短くなる実行表し、\(endposの\)位置が増加すると、最終的なジャンプ源を含んでいました。
具体的には、次
の場合は\(Vの\にU \) そこに\(|分(U)|
= |マックス(V)| +1 \) にする(\ uと)\ジャンプすることができます\を(V \)、\ ( V \)配列が表される\(U \)後置表現、\(endposの(U)\ varsubsetneqq endposの(V)\)


SAMの構築

設定"インクリメンタル方式"を使用し、それは文字列と仮定されてきた\(S \)\(SAM \)は、形成され、追加ノードの一部を変更することになりました\(S + Cの\)\(SAM \)

まず、\(SAM \)各ノードの保つために何を?
接尾辞リンクと、サイドを転送\(|マックス(U)| \) 心の中で便宜上、としてそれを設定し\(レン(U)\) )。これらは、リアルタイムのメンテナンスを持っています。

struct node{
    node *ch[26],*pa;
    int len;
}pool[N*2],*root,*last;

第二に、我々は今に代わって、ミーティングポイントの数を持っている\(S \)サフィックス。
我々は、これらの文字を表すミーティングポイントを見つけることです行う必要があります(C言語\)\転送側、およびいくつかの新しいミーティングポイントの形成。

ミーティングポイントのこの数は、隣接するリンクは、接尾辞で接続されています。
最後の点の前記\(最終\)はならない(C \)を\新しいノードのように、転写エッジである\(CUR \)代表\(endposの= {| S | +1} \) 文字列、最後の\(\ )\(C \)エッジに転送される\(CURの\)
前方の順番で、そこの部分があるかもしれミーティングポイント\(C \)一部にはない、転送側、。
しかしと仮定すると、その点に注意してください\(Pの\)がある転写側の最初のノードのために、それは前のノードの必要があります\(Cの\)転送側。(依頼するかについて考えます)

示されるように、元の非エッジ・ノードの転送のために、転写エッジ\(C \)は、に接続されている\(CURの\)することができます。
特別な場合、この1種の連鎖移動全ての点は、エッジ、直接でない場合\(C \)のソース端にサフィックスリンク。

この時点で、すべてのために転送することができます(CURの\)\ポイントが追いついが出ているが、また知ることができる\(レン(CUR)を= | S | +1 \)、\ (|分(CUR)| =レン(P-)+ 2 \)
のために\(のp \)アカウントにポイントを取って、前方のポイントを開始します。セット\(P \)転送エッジ\(C \)は、の点に接続されている\(Q \)

どこ:\(。レン(P)+ 1 =レン(Q)\)
を直接\(CUR \)からリンク接尾辞\(Q \) 他は変更されません。
(満足\(| MIN(CUR)| =レン(P)+ 2 =レン(P)+ 1 + 1 =レン(Q)+ 1 = |。MAX(Q)| + +1 \)
終了します。

ケース2:\(レン(P-)+1 <レン(q)が\)
満たされていない\(|分(CUR)| = |マックス(Q)| +1 \) それが直接の接尾辞リンクに接続されていません。
代わりに、新しいポイント\(NQ \)に対応する、(Q \)\複製ポイントは、\(Q \)は、コピー側に移した\(NQ \)に。\(レン(NQ)は、レン(P-)+1 \ =) しましょう\(CURの\)\(q個\)サフィックスのリンクが接続されている(NQ \)を\、\ (NQ \)サフィックスのリンクをリードする(q個\)\元接尾リンクを。オリジナルの転写側もする(Qの\)\も転送のエッジをポイントし\(NQ \)

コードは非常に短いです。

void insert(int c){
    node *p=last,*cur=&pool[++cnt];
    cur->len=p->len+1;
    for(;p && !p->ch[c];p=p->pa) p->ch[c]=cur;
    if(!p) cur->pa=root;
    else{
        node *q=p->ch[c],*nq;
        if(q->len==p->len+1) cur->pa=q;
        else{
            nq=&pool[++cnt];
            nq->len=p->len+1;
            for(int i=0;i<26;i++) nq->ch[i]=q->ch[i];
            nq->pa=q->pa;
            q->pa=cur->pa=nq;
            for(;p && p->ch[c]==q;p=p->pa) p->ch[c]=nq;
        }
    }
    last=cur;
}

証明の複雑さ

\(endposの\)等価クラスの数である\(O(N)\)

辺の数\(O(N)\)

私は怠け者だし、この参照のブログを
、それが証明可能であるので、しかし、開くために、アレイの端に注意を払う\(2N \)


アプリケーション

のは、次の分解を聞いてみましょう。


参考資料

CHEN李杰冬のキャンプのコースウェア
でMenciBlogを説明するための
説明最も人気のサフィックスオートマトンの歴史

おすすめ

転載: www.cnblogs.com/lindalee/p/11520144.html