J'ai modifié le titre pour qu'il soit plus compréhensible.
Voici une version détaillée de la question:
Nous avons une chaîne s
et nous voulons la diviser en substrings. Chaque sous-chaîne est différente les unes des autres. Quel est le nombre maximum de sous-chaînes uniques que nous pouvons avoir à partir de n coupé. En d'autres termes, quel est le nombre maximum de sous-chaînes uniques qui concaténent pour former s
.
Voici quelques exemples:
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
Remarque: s
ne contient que des caractères minuscules. Je ne sais pas combien de temps s
et je ne peux donc pas deviner la complexité temporelle optimale. :(
Est-ce un problème NP-difficile? Sinon, comment puis-je le résoudre efficacement?
J'ai entendu ce problème d'un de mes amis et je n'ai pas pu y répondre. J'essaie d'utiliser un Trie + gourmand pour résoudre ce problème. La méthode échoue pour le premier exemple.
Voici la solution Trie que j'ai trouvée:
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
Par exemple 1, le code ci-dessus renverra 3 car il essaie de diviser s
en a|ab|abaa
.
Ajouter: Grâce à l'idée de tout le monde, il semble que ce problème soit très proche d'un problème NP. En ce moment, j'essaie de le penser dans cette direction. Supposons nous avons une fonction Guess(n)
. Cette fonction renverra True
si nous pouvions trouver n
sous-chaînes uniques d'une division ou False
sinon. Une observation ici est que si Guess(n) == True
, alors Guess(i) == True
pour tous i <= n
. Puisque nous pouvons fusionner deux sous-chaînes adjacentes ensemble. Cette observation peut conduire à une solution binaire. Cependant, elle nécessite encore nous pouvons calculer la fonction Guess
très efficacement. Malheureusement, je n'ai toujours pas trouvé de méthode polynomiale pour calculer Guess(n)
.
Mon autre réponse était étroitement lié mais ne correspondait pas exactement à ce problème, laissant ambigu si la recherche de la plus grande factorisation de chaînes sans égalité pourrait être d'une classe de complexité différente que s'il existe une factorisation sans égalité avec une longueur de facteur lié (ce dernier étant traité par l'article cité).
Dans l'article, Pattern matching with variables: Fast algorithms and new hardness results (Henning Fernau, Florin Manea, Robert Mercaş, and Markus L. Schmid, in Proc. 32nd Symposium on Theoretical Aspects of Computer Science, STACS 2015, volume 30 de Leibniz International Proceedings in Informatics (LIPIcs) , pages 302–315, 2015), les auteurs montrent qu'il est NP-complet de décider, pour un nombre donné k
et un mot w
, si w
peut être factorisé en k
facteurs distincts.
Si nous considérons templatetypedef comment , impliquant qu'il pourrait y avoir une solution temporelle polynomiale à la factorisation sans restriction et sans égalité la plus importante, alors nous pourrions sûrement utiliser un tel algorithme pour répondre si nous pouvions diviser la chaîne en k
facteurs distincts (sous-chaînes) en observant simplement si k
est inférieur au maximum que nous connaissons déjà.
Schmid (2016), cependant, écrit que "c'est toujours un problème ouvert que MaxEFF-s reste NP-complet si l'alphabet est fixé." (Computing free-egality and repetitive string factorisations, Theoretical Computer Science Volume 618 , 7 mars 2016, Pages 42-51)
La taille maximale de factorisation sans égalité (MaxEFF-s) est cependant toujours paramétrée et est définie comme suit:
Instance: un mot w
et un nombre m
, 1 ≤ m ≤ |w|
.
Question: Existe-t-il une factorisation sans égalité p de w
avec s(p) ≥ m
? (s(p)
étant la taille de la factorisation.)