Générer tous les sous-chaînes pour une chaîne donnée
Donné une chaîne s
, quelle est la méthode la plus rapide pour générer un ensemble de tous ses uniques des sous-chaînes?
Exemple: pour str = "aba"
nous aurions substrs={"a", "b", "ab", "ba", "aba"}
.
Les naïfs algorithme serait de parcourir l'ensemble de la chaîne de génération de sous-chaînes d'une longueur de 1..n
à chaque itération, ce qui donne un O(n^2)
limite supérieure.
Est une meilleure liés possible?
(ce qui est techniquement devoirs, de sorte que les pointeurs ne sont la bienvenue)
- vous obtenez l'efficacité de l'algo? Merci de le partager si vous l'avez. TIA.
- Je ne me souviens pas vraiment de ce qui s'est passé. Mais plus vraisemblablement, j'ai fini par mettre en place une sorte de suffixe de l'arbre. N'avez pas le code plus, désolé.
- L'algorithme proposé ne pas s'exécuter en O(n2) le temps!
Vous devez vous connecter pour publier un commentaire.
Que d'autres affiches ont dit, il y a potentiellement O(n^2) sous-chaînes pour une chaîne donnée, de sorte que leur impression ne peut pas être fait plus vite que ça. Cependant, il existe une représentation efficace de l'ensemble qui peut être construit en temps linéaire: le suffixe de l'arbre.
Il n'y a aucun moyen de le faire plus vite que O(n2) parce qu'il y a un total de O(n2) sous-chaînes dans une chaîne de caractères, donc si vous avez de les générer tous, leur nombre sera
n(n + 1) /2
dans le pire des cas, d'où lesupérieurde la limite inférieure deO(n2)Ω(n2).Première est la force brute qui a une complexité O(N^3) qui pourrait être ramené à O(N^2 log(N))
Second en utilisant HashSet qui a une Complexité O(N^2)
Troisième à l'aide de LCP, en commençant par la recherche de tous le suffixe d'une chaîne qui a le pire des cas O(N^2) et dans le meilleur des cas O(N Log(N)).
Première Solution:-
Deuxième Solution:-
Troisième Solution:-
Quatrième Solution:-
Pour les grandes oh ... Meilleur que vous pourriez faire serait de O(n^2)
Pas besoin de réinventer la roue, il n'est pas basé sur une des chaînes, mais sur un fixe, de sorte que vous aurez à prendre les concepts et de les appliquer à votre propre situation.
Algorithmes
Vraiment un Bon Livre Blanc à partir de MS
Dans la profondeur de PowerPoint
Le Blog de la chaîne de perms
bien, car il est potentiellement
n*(n+1)/2
différents sous-chaînes (+1 pour le vide sous-chaîne), je doute que vous pouvez être mieux queO(n*2)
(pire des cas). la chose la plus facile est de les générer et d'utiliser certaines de niceO(1)
table de recherche (comme une table de hachage) pour exclure les doublons droite quand vous les trouvez.n(n+1)/2
. "abc" a 3*4/2 = 6 chaînes ("a", "b", "c", "ab", "bc", "abc") non 3*2/2 = 3 sous-chaînes.Il ne peut être fait en o(n^2) total nombre de sous-chaînes d'une chaîne de n(n+1)/2.
Exemple:
string s = "abcd"
passer de 0: (toutes les chaînes sont de longueur 1)
a, b, c, d = 4 cordes
pass 1: (toutes les chaînes sont de longueur 2)
ab, bc, cd = 3 cordes
pass 2: (toutes les chaînes de longueur 3)
abc, bcd = 2 chaînes
pass 3: (toutes les chaînes sont de longueur 4)
abcd = 1 chaînes
En utilisant cette analogie, nous pouvons écrire la solution à o(n^2) le temps de la complexité et de la constante de l'espace de la complexité.
Le code source est comme ci-dessous:
Voici mon code en Python. Il génère tous les possibles sous-chaînes d'une chaîne de caractères.
Si vous passez str_ = "abcdef" à la fonction, il génère les résultats suivants:
a, ab, abc, abcd abcde, abcdef, abcdf, abce, abcef, abcf, abd, abde, abdef, fdea, abe, abef, abf, ac, acd, l'acde, acdef, acdf, ace, l'acef, acf, ad, ade, adef, adf, ae, aef, af, b, bc, bcd, bcde, bcdef, bcdf, bce, bcef, fcc, bd, bde, bdef, bdf, être, bef, bf, c, cd, cde, cdef, cdf, ce, iec, fc, d, de, def, df, e, ef, f
Naïfs algorithme prend O(n^3) au lieu de O(n^2).
Il y a O(n^2) nombre de sous-chaînes.
Et si vous mettez O(n^2) nombre de sous-chaînes, par exemple, de définir
définissez ensuite compare O(lgn) comparaisons pour chaque chaîne pour vérifier si il alrady existe dans le jeu ou pas.
En outre, il prend O(n) fois pour la comparaison de chaînes.
Par conséquent, il prend O(n^3 cgl) de temps si vous utilisez set. et vous pouvez le réduire en O(n^3) si vous utilisez la table de hachage au lieu de set.
Le fait est que c'est des comparaisons de chaînes de pas le nombre de comparaisons.
Donc l'un des meilleurs de l'algorithme disons que si vous utilisez le suffixe tableau et le plus long préfixe commun (LCP) de l'algorithme, il réduit O(n^2) pour ce problème.
La construction d'un suffixe tableau à l'aide de O(n) en temps de l'algorithme.
Temps pour LCP = O(n) fois.
Puisque, pour chaque paire de chaînes dans le suffixe de tableau, ne LCP si le temps total est O(n^2) le temps de trouver le longueur distincts subtrings.
D'ailleurs, si vous voulez impression tous distincts des sous-chaînes, il faut O(n^2).
Ce tirages uniques des sous-chaînes.
https://ideone.com/QVWOh0
Essayer ce code à l'aide d'un suffixe tableau et le plus long préfixe commun. Il peut aussi vous donner le nombre total de unique de sous-chaînes. Le code peut donner un débordement de pile dans visual studio, mais fonctionne très bien dans Eclipse C++. C'est parce qu'il renvoie des vecteurs de fonctions. N'ai pas testé contre de très longues chaînes. Va le faire et d'en rendre compte.
Et voici un simple algorithme:
Les deux algorithmes listé tout simplement trop lent pour de très longues chaînes de bien. J'ai testé les algorithmes à l'encontre d'une chaîne de caractères de longueur de plus de 47 000, et les algorithmes ont pris plus de 20 minutes à remplir, avec la première prise de 1200 secondes, et le second, la prise de 1360 secondes, et ce n'est que le comptage de l'unique sous-chaînes sans la sortie du terminal. Donc, pour probablement les cordes de longueur jusqu'à 1000 vous pourriez obtenir une solution de travail. Les deux solutions n'a calculer le même nombre total d'uniques des sous-chaînes bien. Je l'ai fait tester à la fois les algorithmes contre les longueurs de chaîne de 2000 et 10 000. Les temps étaient pour le premier algorithme: 0.33 s et 12 s; pour le second algorithme, il était 0.535 s et 20 s. De sorte qu'il ressemble en général le premier algorithme est plus rapide.
Beaucoup de réponses qui comprennent le 2 boucles for et .substring() appel de demande O(N^2) le temps de la complexité. Cependant, il est important de noter que le pire des cas pour un .substring() appel en Java (après la mise à jour 6 de Java 7) est O(N). Donc, en ajoutant un .substring() appel dans votre code, de l'ordre de N a augmenté de par un.
Donc, 2 boucles for et .substring() appel à l'intérieur de ces boucles, égale à O(N^3) le temps de la complexité.
Vos programmes ne sont pas de donner unique sbstrins.
S'il vous plaît tester avec entrée
abab
et de sortie doivent êtreaba,ba,bab,abab
.