1

個人的なプロジェクト用にコーディングしている検索機能のために、線形時間で直接 DAWG を作成する一連の関数を実装しようとしています。この論文を読んで、たまたま DAWG の背後にあるアイデアを詳述し、線形時間での構築のための疑似コードさえ提供しています!

ただし、疑似コードに従うと、(私の目には)トライのような構造が得られるようです。具体的には、サフィックスが明示的に共有されているようには見えません (実際にはグラフのエッジで接続されています)。代わりに、グラフの実際のトラバーサルに実際には関係のない接尾辞ポインターによって表されます。

たとえば、セット内の単語の DAWG のこの図を見てください{tap, taps, top, tops}( DAWG ウィキペディアのページから)。

ここに画像の説明を入力

ここで、前述の論文で詳述されているこれらの手順に従って得られる構造と比較してください (この一連の単語を使用して手動で行うには、ごくわずかな時間がかかります)。

Note: Edges are labeled by letters
      Nodes are labeled by the concatenation of the labels of the primary edges
      used to reach them
      Suffix pointers are not visually represented on the graph

      primary edges:   solid edges used to traverse graph
      secondary edges: dotted edges implying a suffix relationship between
                       the letter labeling the edge and the substring 
                       represented by the target node

builddawg(S)
    1. Create a node named source.
    2. Let activenode be source.
    3. For each word w of S do:
        A. For each letter 'a' of w do:
            Let activenode be update (activenode, a).
        B. Let activenode be source.
    4. Return source.


update (activenode, a)
    1. If activenode has an outgoing edge labeled 'a', then
        A. Let newactivenode be the node that this edge leads to.
        B. If this edge is primary, return newactivenode.
        C. Else, return split (activenode, newactivenode).
    2. Else
        A. Create a node named newactivenode.
        B. Create a primary edge labeled 'a' from activenode to newactivenode.
        C. Let currentnode be activenode.
        D. Let suflxnode be undefined.
        E. While currentnode isn’t source and sufixnode is undefined do:
            i. Let currentnode be the node pointed to by the suffix
               pointer of currentnode.
            ii. If currentnode has a primary outgoing edge labeled 'a',
                then let sufixnode be the node that this edge leads to.
            iii. Else,if currentnode has a secondary outgoing edge labeled 'a' then
                a. Let childnode be the node that this edge leads to.
                b. Let suffixnode be split (currentnode, childnode).
            iv. Else, create a secondary edge from currentnode to newactivenode
                labeled 'a'.
        F. If sufixnode is still undefined, let suffixnode be source.
        G. Set the suffix pointer of newactivenode to point to sufixnode.
        H. Return newactivenode.


split (parentnode, childnode)
    1. Create a node called newchildnode.
    2. Make the secondary edge from parentnode to childnode into
       a primary edge from parentnode to newchildnode (with the same label).
    3. For every primary and secondary outgoing edge of childnode,
       create a secondary outgoing edge of newchildnode with the
       same label and leading to the same node.
    4. Set the suffix pointer of newchildnode equal to that of childnode.
    5. Reset the suffix pointer of childnode to point to newchildnode.
    6. Let currentnode be parentnode.
    7. While currentnode isn’t source do:
        A. Let currentnode be the node pointed to by the 
           suffix pointer of currentnode.
        B. If currentnode has a secondary edge to childnode,
           then make it a secondary edge to newchildnode (with the same label).
        C. Else, break out of the while loop.
    8. Return newchildnode.

私が得た構造は、上に描かれたものと同等ではありません。実際、二次エッジを一次エッジに変換することによって余分なノードが生じることを除けば、トライとほとんど同じように見えます。上記の DAWG に相当するトライは次のとおりです。

ここに画像の説明を入力

アルゴリズムを間違って適用しているだけですか、DAWGSにはいくつかのタイプがありますか、それともDAWGがどのように見えるべきかを誤解しているだけですか?

DAWG の詳細を調べたほとんどの論文には、アルゴリズムによって作成されたように見える構造がありますが、オンラインで読んだほとんどの資料 (および私が見た写真) には、共通の接尾辞を接続する実際のエッジがあります。何を信じればいいのか、実際に同等かどうかはわかりません。

4

1 に答える 1

1

私は解決策を見つけたと信じています。

DAWG を構築した後、ノードを上から下に繰り返し処理し、それらのサブツリーを削除して、それらを指すsuffixPointer != sourceノードに直接接続することができます。suffixPointer

于 2012-07-23T20:24:22.347 に答える