タイトルをわかりやすくするために変更しました。
これは質問の詳細なバージョンです:
文字列s
があり、それをsubstringsに分割したいとします。各部分文字列は互いに異なります。 one cutから取得できる一意の部分文字列の最大数はいくつですか。言い換えると、s
を形成するために連結する一意の部分文字列の最大数はいくつですか。
ここではいくつかの例を示します。
_Example 1
s = 'aababaa'
output = 4
Explain: we can split `s` into aa|b|aba|a or aab|a|b|aa,
and 4 is the max number of substrings we can get from one split.
Example 2
s = 'aba'
output = 2
Explain: a|ba
Example 3
s = 'aaaaaaa'
output = 3
Explain: a|aa|aaaa
_
注:s
には小文字のみが含まれます。 s
の長さについては知らされていないため、最適な時間の複雑さを推測することはできません。 :(
NP難しい問題ですか?そうでない場合、どうすれば効率的に解決できますか?
友人の一人からこの問題を聞いたが、答えられなかった。私はこの問題を解決するためにTrie +貪欲を使用しようとしています。最初の例では、メソッドは失敗します。
これが私が思いついたTrieソリューションです:
_def triesolution(s):
trie = {}
p = trie
output = 0
for char in s:
if char not in p:
output += 1
p[char] = {}
p = trie
else:
p = p[char]
return output
_
たとえば、上記のコードは、s
を_a|ab|abaa
_に分割しようとしているため、3を返します。
追加:みんなのアイデアのおかげで、この問題はNP問題に非常に近いようです。今、私はこの方向から考えようとしています。たとえば、関数Guess(n)
があります。この関数は、1つのスプリットからTrue
一意の部分文字列を検出できた場合はn
を、そうでない場合はFalse
を返します。 if if Guess(n) == True
、then Guess(i) == True
for all _i <= n
_。隣接する2つの部分文字列をマージできるため、この観察はバイナリソリューションにつながる可能性があります。 Guess
関数を非常に効率的に計算できますが、残念ながら、私はGuess(n)
を計算する多項式の方法を見つけることができませんでした。
私の他の answer は密接に関連していましたが、この問題に正確に対応していませんでした。バインドされた因子の長さ(後者は引用された論文で扱われています)。
論文では、変数とのパターンマッチング:高速アルゴリズムと新しい硬度の結果(Henning Fernau、Florin Manea、RobertMercaş、Markus L. Schmid、の第32回コンピュータの理論的側面に関するシンポジウムScience、STACS 2015、Leibniz International Proceedings in Informatics(LIPIcs)、pages 30–315、2015)の30巻、著者は、与えられた数について、決定することはNP完全であることを示しています。 k
と単語w
、w
をk
異なる因子に因数分解できるかどうか。
Templatetypedefの comment を考慮すると、無制限で最大の等値のない因数分解に対する多項式時間の解が存在する可能性があることを意味し、文字列をk
は、k
が既知の最大値よりも小さいかどうかを単に観察することにより、異なる要素(部分文字列)を区別します。
しかし、Schmid(2016)は、「アルファベットが修正された場合、MaxEFF-sがNP完全のままであるかどうかは未解決の問題です」と書いています。 (同等性のない反復的な文字列因数分解の計算、理論的コンピューターサイエンスボリューム618、2016年3月7日、ページ42-51)
ただし、最大不等分解因数分解サイズ(MaxEFF-s)は引き続きパラメーター化されており、次のように定義されます。
インスタンス:単語w
と数字m
、_1 ≤ m ≤ |w|
_。
質問:s(p) ≥ m
とw
の等式のない因数分解pはありますか? (s(p)
は因数分解のサイズです。)