最長共通部分文字列アルゴリズムを学習したばかりなので、この問題の特定の変形に興味がありました。次のように説明されています-:
文字列の 2 つの空でないシーケンス、X = (x1, x2, x3,....,x(n)) および Y = (y1, y2, y3,..., y(m)) が与えられます。ここで、x (i) と y(i) は文字列です。Y のすべての文字列の部分文字列である X で最も長い文字列を見つけます。
substring(x, y)
x が y の部分文字列であるかどうかを表すブール値を返す関数があります。明らかに、Y のすべての文字列を連結して、たとえば B で示される 1 つの大きな文字列を形成する必要があります。次のアプローチを考えました。
- Naive : X 内のすべての文字列を連結して、文字列 A(n) を形成することから始めます。substring(A(n), B) を適用します。これには、文字列 A(n) の逆方向の反復が含まれます。true の場合、アルゴリズムはここで終了し、A(n) を返します。または、その部分文字列に含まれる部分を返します。そうでない場合は、(A(n - 1), B) などの適用に進みます。そのような文字列が X に存在しない場合は、空の文字列を返します。
明らかに、このアプローチは、実装によってはかなりの実行時間がかかります。反復アプローチを使用すると仮定すると、反復ごとに、そのレベル/インデックスで文字列を逆方向に反復し、その後 substring() を適用する必要があります。substring() によっては、少なくとも 2 つのループとO(size(B) * maxlength(x1, x2,...))
最悪の場合の時間、またはそれ以上の時間がかかります (間違っている場合は修正してください)。
サフィックスツリー/配列に基づく2番目のアプローチを考えました。
- Generalized Suffix Tree
O(maxlength(y1, y2,...)
: (?)で Ukkonen のアルゴリズムを使用してシーケンス Y の GST を構築します。接尾辞ツリーに関する私の知識の欠如が噛みつきます。サフィックスツリーのアプローチは、部分文字列を見つけるための実行時間を(スペースを犠牲にして)大幅に短縮すると信じていますが、操作を実装する方法がわかりません。
より良いアプローチがあれば、知りたいです。
編集:トピックを放棄したように見えた場合はお詫び申し上げます。
GST ではなく、スタック、キュー、セット、ヒープ、プライオリティ キューなどの標準的なデータ構造を使用するとどうなりますか? シーケンス X は、当然、最大の文字列から順に並べ替える必要があります。文字列配列に格納する場合、mergesort/quicksort などの並べ替えアルゴリズムを使用する必要があります。目標は、可能な限り最も効率的な実行時間を取得することです。
X を、それ自体を構築するときに要素を自動的にソートする構造に格納することはできませんか? 最大ヒープはどうですか?
この方法で部分文字列を見つけるには、サフィックス ツリーが最適な方法のように思われます。他に使用できるデータ構造はありますか?