2011-07-17 3 views
8

問題は説明が簡単です:2つの大きな配列(32ビットの整数値)があり、与えられた数の連続した位置(n)を超えるすべての共通の配列を見つけなければなりません。例えば2つの大きな配列で最も長い文字列の一致を得るために使用するアルゴリズムはどれですか?

、N = 3と比較するための配列の場合:

a = [1, 3, 5, 7, 3, 2, 7, 4, 6, 7, 2, 1, 0, 4, 6] 
b = [2, 5, 7, 3, 2, 3, 4, 5, 6, 3, 2, 7, 4, 6, 0] 

algoritmhは、二つの配列を返すべきである:最初の配列に、

r0 = [5, 7, 3, 2] 
r1 = [3, 2, 7, 4, 6] 

(またはそれをその相対位置および連続するバイトの数が一致した場合)。

私は良い点はLongest Common Substring Algorithmだと思っていますが、誰かが私の問題によく合ったアルゴリズムを知っているかもしれません。私が正しくあなたを理解し、nは、 その後I'deはボイヤー - ムーアの検索アルゴリズムのバリエーションを使用する配列の最小サイズである場合

+0

これは、[Math.stackexchange](http://math.stackexchange.com/) – genesis

+0

に属しています。これは、DNA配列の照合/整列という文脈でしばしば研究されているオープンな研究課題です。あなたは、人がDNAを使ってどのようにこれをやっているかを調べたり、いくつかの利用可能なライブラリを見つけたりすることで、より良い運があるかもしれません。 –

+1

@マーク:これはオープンな研究課題とはどのようなものですか? –

答えて

5

私は接尾辞木を使用してLCSを見つけるためのアルゴリズムを考えます完璧なフィット感です。同じ方法で接尾辞ツリーを構築しますが、最終段階では、両方の文字列の子孫を持つ最も深いノードは探していません。両方の文字列の子孫を持つn以上の深さのすべてのノードを探しています。

+1

これは答えです。 –

-1
+0

しかし、BMアルゴリズムは文字列検索ではありませんか?私の問題は、2つの大きな文字列の間のすべての部分文字列を見つけることです。 – Ivan

+0

文字列は本質的に1つのドメインの数字のシーケンスなので、基本的に問題はありません。 可能なすべてのarray_size/nシーケンス(位置iからi + n、i + 1からi + 1 + n ...まで)として検索し、BMを実行するように部分文字列を設定することができます。 (より大きい同一シーケンスが存在する場合は、最初のnサイズのシーケンスがあり、大きなサフィックスのテストを続けることができます) – sternr

+1

いいえ、BMは文字列内の部分文字列を検索するために使用されます。 – woliveirajr

1

あなたが参照しているウィキペディアのページのアルゴリズムは、あなたが望むものをほぼ正確に行うと思います。最長の回答だけを保持するのではなく、一定のサイズ以上のすべての回答を保持するように修正する必要があります。たとえば、そのページの動的プログラミングソリューションは、次のように変更できます。

function LCSubstr(S[1..m], T[1..n], min_size) 
    L := array(1..m, 1..n) 
    ret := {} 
    for i := 1..m 
     for j := 1..n 
      if S[i] = T[j] 
       if i = 1 or j = 1 
        L[i,j] := 1 
       else 
        L[i,j] := L[i-1,j-1] + 1 
       if L[i,j] >= min_size 
        ret := ret ∪ {S[i-z+1..z]} 
    return 

これは、接頭辞と最長一致を含みます。それらは、Lに見つかった文字列を追跡し、それが拡張子を持つことがわかったときにリターン・セットから接頭辞を取り除くことによって除外することができます。

+0

+1ですが、mとnが大きい場合、OPが主張しているように、O(mn)DPソリューションの代わりにO(m + n)の汎用サフィックスツリーソリューションが本当に必要であることを強調したいと思います。 –

関連する問題