2011-07-09 2 views
6

文字列のリストの最も長い共通接頭辞を見つけるためにどのようなアルゴリズムをお勧めしますか?文字列のリストのすべての共通接頭辞を見つけるための文字列アルゴリズムの提案

私は、次のような文字列を持っているかもしれません:私は、次の接頭辞を知りたい

Call Mike and schedule meeting. 
Call Lisa 
Call Adam and ask for quote. 
Implement new class for iPhone project 
Implement new class for Rails controller 
Buy groceries 

を:

"Call " 
"Implement new class " 

私はObjective Cのを使用することがありますので、既製ココアソリューションは次のようになりますプラス(必須ではありませんが)。

+0

's'は' s'がリスト内の2つの文字列の共通接頭語で、 's'が同じ2つの文字列の他の共通接頭辞の厳密な部分文字列でないようにしたい's'は空の文字列ではありませんか? '{" a1 "、" a2 "、" ab1 "、" ab2 "}'、あなたは '' a ''をしたいのですか? –

+0

はい、そうです。そして、いいえ、私は必要ない。 – cfischer

答えて

2

これは、プレフィックスを考慮する意思の有無によって異なります。

一般的な答えは、すべての文字列をn元のツリーに格納するTrie(おそらくサフィックスツリー)を作成することです。複数の子を持つランクnのすべてのノードを選択することができ、あなたの「プレフィックス」の基準(たとえば、n文字)に応じて、http://en.wikipedia.org/wiki/Trie

enter image description here

参照してください。

繰り返しプレフィックスのリストがあります。

3

trie(別名プレフィックスツリー)にすべての文字列を挿入できます。次に、複数の子を持つノードが見つかるまで(またはノードに2番目の子を追加するときに文字列の挿入を停止する)まで、ルートからトライをトラバースします。

+0

したがって、最初の文字列が "a"で、2番目の文字列が "b"の場合、残りの4300万文字列をトライに挿入する必要がありますか? ;-p –

+0

良い点、私は私の答えを編集しました。 – omz

+0

分岐点に達したときに「文字列の挿入をやめるのではなく」次の文字列に移動するのが嫌です。後者は、「文字列を挿入するとき、挿入する(その文字列)...」とは対照的に、完全に停止することを示唆するかもしれない。しかし、私はあなたが意味することを知っています。 –

6

編集:明確に質問には:文字列

  • が隣り合う
  • ソートの最長の共通のプレフィックスを検索して、共通の接頭辞を重複排除、その後の厳格な接頭辞だといういずれかを削除

    1. ソート別の

    実際には、ステップ(3)のみ、あなたが代わりに並べ替えのトライまたは任意に行うことができた、別のデュープ/プレフィックスだそのいずれかを削除する必要があります。実際には、適切に注釈を付けられたトライですべてを高速化することができます。各ノードに「カウント」を含めると、カウントが2以上のノードが正確に検索されます。 2+のカウント。

    並べ替えが組み込まれていれば、隣接する項目を見ることで接頭辞を検出できるので、おそらくそれほど労力はかかりません。

    [オリジナルの答え:

    ただ、一回限りの操作は、すべての文字列間の最長の共通のプレフィックスを見つけますか?

    私は恐らく接頭語の長さの点でそれをするでしょう。擬似コードにおいて、およびNULで終わる文字列を想定:

    prefixlen = strlen(first_string); 
    foreach string in the list { 
        for (i = 0; i < prefixlen; ++i) { 
         if (string[i] != first_string[i]) { 
          prefixlen = i; 
          break; 
         } 
        } 
        if (prefixlen == 0) break; 
    } 
    
    common_prefix = substring(firststring, 0, prefixlen); 
    

    ]

  • +1

    +1、1回の操作の場合、トライを使用すると時間/空間ペナルティが発生します。 – abeln

    +0

    また、入力文字列がソート順である場合、最初と最後の文字列を比較するだけで済みます。 –

    +0

    これは私が必要とするものではありません。私はn個の文字列の最長共通接頭語を一つも必要としません。むしろ、n個の文字列に対してm個の最も長い共通接頭語が必要です。 – cfischer

    0
    1. トライ・データ構造内のすべての文字列を挿入します。
    2. ルートからのDFSは、1つ以上のエッジが外に出ている最初のノードを検出します。
    3. ルートからステップ2で計算されたノードまでのパスは、すべての文字列セットの最長共通接頭辞を示します。
    関連する問題