web-dev-qa-db-ja.com

文字列にパターンを挿入するすべての可能な方法を見つける

私はこの問題についてしばらく考えていましたが、再帰的な解決策しか見つかりませんでしたが、動的計画法があると感じており、理解できません。これは私が知らない有名な問題ですか?


Q:文字列とパターンが与えられた場合、パターンの文字を文字列と(順番に)一致させる一意の方法の数を返します。

明確化:一致を見つけるには、パターンの最初の文字を取得し、文字列内の最初の一致する文字を見つけてから、パターンの2番目の文字を取得し、以前に一致した後の文字列の最初の一致する文字と一致しますキャラクター。

例1(4つの一致):

文字列:DABBCDDE

パターン:ABD

考えられる方法(太字はパターンが文字列と一致する場所です):

  • D [〜#〜] ab [〜#〜] BC [〜#〜] d [〜#〜] DE
  • D [〜#〜] a [〜#〜] B [〜#〜] b [〜#〜] C [〜#〜] d [ 〜#〜] DE
  • D [〜#〜] ab [〜#〜] BCD [〜#〜] d [〜#〜] E
  • D [〜#〜] a [〜#〜] B [〜#〜] b [〜#〜] CD [〜#〜] d [ 〜#〜] E

例2(0一致):

文字列:ABC

パターン:BCA

(B、Cに一致し、文字列の最後にいる場合、前の文字に戻って一致することはできません)


再帰的なアプローチでは、文字列(sIndex)とパターン(pIndex)の現在のインデックスを追跡するメソッドがあります。 string [sIndex]がpattern [pIndex]と一致する場合、メソッドを再度呼び出し、sIndexとpIndexを増やします。そうでない場合は、sIndexを増やして、一致するものを見つけてください。このメソッドは、再帰呼び出しの戻り値が合計されるため、合計数を返します。 (一致は1を追加し、一致は0を追加しません)

基本ケース:

  • PIndexがパターンの長さより大きい場合、0を返します。

  • SIndexが文字列の長さよりも大きい場合は、1を返します(一致するものが見つかりました!)


他にどのような解決策がありますか?

7
Daniel Olsson

これを解決するために動的計画法を使用する必要はないと思います。これが解決策だと思います:

  1. 最初に、リストのリストを作成して、指定されたテキストのパターン内の文字の出現を維持します。

  2. こんな感じになります

次の図:

   A    B    D 
             0 
   1 -> 2 -> 5
        3    6 
  1. これは、(0-indexingを想定して)Aが0番目の位置で発生し、Bが2,3の位置で発生し、Dが0,5,6の位置で発生することを意味します。

  2. 連続する列(ここではA、BおよびB、D)のペアごとに、ポインターを使用して、列内の対応する値を次の列内の次に大きい値にマップします。ここで、1(col1内)には2(col2内)へのポインターがあり、2(col2内)には5(col3内)へのポインターがあります。0は2より小さいためです。3(col2内)には5(col3内)へのポインターがあります。 )(ここでは描画できませんでした)。

  3. 最初の列の値ごとに、ポインターを使用して可能な方法の数を見つけます。ここで1-> 2および2-> 5なので、可能なウェイの数は2 * 2ウェイです(つまり、1-> 2-> 5、1-> 2-> 6、1-> 3-> 5、1)。 -> 3-> 6)。 Aの各値について、列の残りの要素の数を掛けるだけです。

  4. ここでは、Column1(つまり、A)の値が1つだけ存在します。複数の列がある場合は、ポインターを使用してAの各値の値を計算し、それらすべてを合計してウェイの数を取得します。

  5. 複雑さはO(n)で、リストの作成はO(n)、ポインタースペース、作成時間はO(n)だと思います。

1
kaushalpranav