最長の繰り返しサブシーケンスを見つける


9

文字列与えられた場合、最も長い繰り返し(少なくとも2回)のサブシーケンスを見つけたいと思います。つまり、私は、文字列検索したいwののサブシーケンスである(連続している必要はありません)ように、W = ワット"ワットを"。つまり、wは半分が連続して2回現れる文字列です。wsのサブシーケンスですが、必ずしもサブストリングではないことに注意してください。swsw=wwwws

例:

「ababccabdc」の場合は「abcabc」になります。これは、「ababccabdc」に「abc」=「abc」と「abc」が(少なくとも)2回表示されるためです。

「addbacddabcd」の場合、「dd」は2回表示されるため、1つのオプションは「dddd」です(同じ文字を複数回使用することはできませんが、ここでは4つの「d」があるので問題ありません)。ただし、lebngth 4です。長さ8の場合: 'abcdabcd'は、 'abcd'が 'addbacddabcd'のサブストリングであるため、2回出現します。

最長の繰り返しサブシーケンスを見つけることに興味があります。これは「最長/最大の正方形を見つける」とも呼ばれますが、正方形が部分列ではなく部分列に対して定義されている多くの記事を読みました。

文字列のブレークポイントのすべてのオプションを反復することでを取るブルートフォースアルゴリズムを簡単に使用できます。次に、最大/最長の共通サブシーケンスを検索する2つの文字列を作成しますが、各チェックは動的プログラミング手法を使用してO n 2を取るため、全体の時間はO n 3)になります。私はO n 2をとる最も長い共通部分列のためのより効率的なアルゴリズムを見つけましたO(n3)O(n2)O(n3)なので、実行時間はOn3O(n2logn)O(n3logn)

私は最長の繰り返しサブシーケンス問題のためのより効率的なアルゴリズムを探しています。おそらく、すべてのブレークポイントを反復するという私の考えは、時間を浪費しすぎて、反復回数を減らすことができます。あるいは、異なる姿勢のアルゴリズムがこの問題を解決できるかもしれません。

私は多くのジャーナルや以前の質問で検索してきましたが、私が見つけた結果のほとんどは部分列ではなく部分文字列に関するものでした。

これはサフィックスツリーを使用して実行できることも読みましたが、これもサブストリングに関連しており、そのようなアイデアをサブシーケンスに拡張できるかどうかはわかりません。

時間で実行されるソリューションを探しています。時間の1が存在する場合にはO nはログn個でも良くなる(そのようなものが存在する場合、私はわかりません)。O(n2)O(nlogn)


4
サフィックスツリーまたはサフィックス配列を検索します。
仮名2015

1
o(n2)nuvxuxvxn+1$uvo(n2)xuv

O(n+m)O(nlogn)

@悪:まだ方法がわかりません。もう少し詳しく教えてください。(あなたはあなたがそれらの時間の複雑さで解決できる最長の共通部分文字列を考えていませんか?)
j_random_hacker

o(n2)

回答:


-1

ここに動的プログラミングソリューションがあります。

x1xnT0,,nnT[nn]

T[i,j]={0if i=0 or j=0,T[i1,j1]+1if xi=xj and ij,max(T[i1,j],T[i,j1])otherwise.
T[n,n]

私たちはいくつかであると仮定と、そしてあなたの中に条件文は真です。次に、位置の文字が両方のサブシーケンスの一部であることを意味します。i = j +i,ji 1 = ji=j+1ifdp[i][j] = dp[i - 1][j - 1] + 1i1=j
j_random_hacker

3
コンピュータサイエンスへようこそ!ソースコードを削除して、アイデア、疑似コード、および正しい引数に置き換えてください。関連するメタディスカッションについては、ここここを参照してください。
ラファエル

@Raphael再帰的な式はソースコードとしてカウントされません。
Number945

1
@BreakingBenjamin選択した言語に応じて、与えられた繰り返しを文字通り多かれ少なかれ書き留めることができます。ここでは説明がないのがポイントです。
ラファエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.