別の文字列を再構築するための部分文字列のサブセットが存在しますか?
-
28-09-2020 - |
質問
私は、与えられた部分文字列セットを使用して特定の文字列を再構築できるかどうかをチェックするための高性能アルゴリズムを探しています。詳細:
私たちの文字列がアルファベットの上にあるとしましょう $ \ sigma $ 。
入力:
- 文字列 $ s \ in \ sigma ^ * $
- 文字列の有限セット $ A={a_1、a_2、...、...、a_2、...、a_n \} \ subset \ sigma ^ * $ 。
出力:
- $ \ exists m:\ exists b_1、b_2、\ ldots、b_m \ in a:b_1 + b_2 + \ cdot + b_m= s $
ここで、 $ + $ は文字列の連結です。
たとえば、 $ s= {} $ s= {} $ s= {} $ A={$ " $ ab $ " $、$ < / span> " $ cd $ " $、$ " $ AC $ " $ \} $ 、答えはtrueです。 この質問の目的のために、 $ A $ の文字列を複数回再利用できます。解決
$ a $ の文字列を再利用する場合は、動的プログラミングで解決できます。まず、 $のストレージ文字列を保存します。プレフィックスツリー内の$ (ただの逆の接尾辞ツリー link ) $ s [i:end] $ の場合、再帰的にdetrmine $ a $ : $ \ etell $ 文字列の長さになり、wlogは $ s $ が $ \ $$ と $ A \ \ \ \ \ {\ $ \} $ 。 MOROEVER、 $ m [i] \ in \ {0,1 \} $ $ $ s [i:\ $ $ は、 $ a $ の要素によって構築できます。 $ m [i] \ gets \ infty $ $ i= 0、\ dots、\ etr-1 $ < / span>と $ m [\ etell]= 1 $ ( $ s [\ erell]=$$ < /スパン>) さて、 $ f(i)$ は、 $ m [i] $ を再帰的に計算する関数です。それはすでに計算されていません。 $ f(i)$ が呼び出された場合、 $ a $ の接尾辞ツリーのルートから始まります。 index $ s [i]、s [i + 1]、\ dots 対応するノードが $ a $ にあるように、 $ f(j)を再帰的に呼び出します。 $ 。 $ 1 $ を返す場合は、 $ m [i]= 1 $ を設定し、 $ 1 $ 。それ以外の場合は、 $ s [j + 1]、s [j + 2]、\ dots のトラバーサルでプロセスを繰り返します。 -container "> $ A $ 、または葉が到達します。成功がない場合は、 $ m [i]= 0 $ を設定し、 $ 0 $ を返します。問題を決定するには、 $ f(1)$ を呼び出します。最悪の場合の複雑さは複雑さです。 $ \ ell d $ 、 $ d $ が深さである接尾辞ツリー( $ a $ の最長シーケンス)、プレフィックスツリーの構築コスト。
ワーストケースシナリオは、1つの解決策が見つかったとすぐに再帰的な呼検索が停止するため、再帰呼び出し検索が停止するため、回避されます。そのため、実際には、 $ \ etell d $ の部分ははるかに少ないかもしれません。サフィックスツリーの構成は、 $ a $ に応じて高価になる可能性があります。ただし、 $ a $ が $ s $ に使用されている場合、コストは償却されます。 $ a $ が本当に大きくて $ s $ が短い場合は、要素をソートするほうがよいかもしれません。 $ a $ の場合は、トラバースの代わりにバイナリ検索を行います。