2016-10-13 11 views
0

次の問題に対するソリューションを実装する方法:
シンボルとパターンの文字列を指定すると、いつでも追加できます。各パターンの発生頻度をカウントします。シンボルパターンと動的パターンの一致

は:
のは、いつでも例(B A C)ための新しいパターンを登録することができA B A C D E ... ユーザーを言わせて入力シンボルの連続的な流れがあります。パターンが2番目のタイムステップの前に登録された場合、パターンは1回カウントされます。最初のパターンは、例えば(B A C)(CとD)をカウントしなければならない重複パターンの場合

のみ(B A C)がカウントされてしまいます。

ソリューションはに近づく:
自明な解はただ、パターンごとに1つのポジションをキープパターンが一致したときに、それを進めると、1が一致したら、すべての位置をリセットすることです。これはO(n * m) のランタイムにつながり、nはストリームの長さであり、mは最も長いパターンの長さです(たとえば、すべてのパターンに長さm - 1の同じプレフィックスを持つことによって)。

代替のアプローチは、有限オートマトンを構築し、パターンに接頭辞を組み合わせることができるという事実を使用することです。

  • がどのようにパターン間のエッジを構築する: Example automata

    しかしそれにはいくつかの問題がありますか? (例えばB D EBから)

  • 実行時にパターンを追加する方法。例えば。ストリームがA Bであり、現時点でパターン(A B C)のみが登録されているとします。ユーザは(B A C)を登録します。ストリームがA C D Eに続く場合。登録する前に最初のシンボルが発生したため、パターンは一致しません。

アイデアはAho Corasick algorithmにリンクできます。しかし、アルゴリズムはパターンのすべての出現と一致し、最初のものだけではありません。実行時にパターンを追加することはできません。

答えて

1

Aho-Corasick FSMの最初は空のリストを維持します。新しいパターンが登録されるたびに、このパターンだけの新しいFSMを作成し、それをリストに追加し、リストの最後に2つの単一文字列FSMがあるかどうかチェックします:もしそうなら、それらを削除し、 2つの2弦FSMがあるかどうかをチェックし、もしそうなら1つの4弦FSMに結合してください。すべてのFSMが異なる文字列数になるまで、2つのkストリングFSMを1つの(2k)ストリングFSMに結合するこの手順を繰り返します。 (同じ数の文字列に対して2つのFSMがリスト内の隣接位置になければならないことに注意してください)

n個の登録が合計で発生したとします。上記の「圧縮」手順の結果、リストには常にlog2(n)+1のFSMが含まれるため、の全体的な「コストファクタ」は、入力ストリームを検索するためにこれらのFSMのそれぞれを(vsすべての文字列を含む単一のFSM)はO(log n)である。また、特定の文字列が参加するFSM構築プロセスの数は、log2(n)+1で上限が設定されます。これは、構築に参加する新しいFSMが、それが構築に参加した以前のFSMの必然的に2倍です。したがって、の全体的な "コストファクタ"すべてのFSM(すべての文字列を含む単一のFSMを構築することと比較して)もO(ログn)です。

関連する問題