Plus longue sous-séquence commune de 3+ chaînes
Je suis en train d'essayer de trouver la plus longue sous-suite commune de 3 ou plus de chaînes. L'article de Wikipédia a une grande description de comment faire pour les 2 chaînesmais je suis un peu incertain de la façon de prolonger ce de 3 ou plus de chaînes.
Il ya beaucoup de bibliothèques pour trouver la CL de 2 cordes, donc je voudrais utiliser l'un d'eux si possible. Si j'ai 3 chaînes A, B et C, est-il valide pour trouver la CL de A et B de X, et ensuite trouver la CL de X et C, ou est-ce la mauvaise façon de le faire?
J'ai implémenté en Python comme suit:
import difflib
def lcs(str1, str2):
sm = difflib.SequenceMatcher()
sm.set_seqs(str1, str2)
matching_blocks = [str1[m.a:m.a+m.size] for m in sm.get_matching_blocks()]
return "".join(matching_blocks)
print reduce(lcs, ['abacbdab', 'bdcaba', 'cbacaa'])
Ce sorties "ba", mais elle doit être "baa".
source d'informationauteur del
Vous devez vous connecter pour publier un commentaire.
Simplement généraliser la relation de récurrence.
Pour les trois chaînes:
Devrait être facile de généraliser à plus de cordes à partir de ce.
À trouver la plus Longue sous-suite Commune (LCS) de 2 chaînes A et B, vous pouvez parcourir un tableau en 2 dimensions, en diagonale, comme indiqué dans le Lien que vous avez posté. Chaque élément du tableau correspond à la difficulté de trouver la CL de la chaˆ ıne A' et B' (Une coupe par son numéro de ligne, B coupé par son numéro de colonne). Ce problème peut être résolu par le calcul de la valeur de tous les éléments du tableau. Vous devez être certain que lorsque vous calculez la valeur d'un élément de tableau, tous les sous-problèmes requis pour calculer cette valeur a déjà été résolu. C'est pourquoi vous traversez le tableau en 2 dimensions en diagonale.
Cette solution peut être mise à l'échelle à la recherche de la plus longue sous-suite commune entre la N des chaînes, mais cela exige qu'un moyen pour parcourir un tableau à N dimensions telle que tout élément est atteint que lorsque tous les sous-problèmes de l'élément nécessite une solution a été résolu.
Au lieu de l'itération N-dimensions tableau dans un ordre particulier, vous pouvez également résoudre le problème de manière récursive. Avec la récursivité, il est important d'enregistrer les solutions intermédiaires, depuis de nombreuses branches, les mêmes solutions intermédiaires. J'ai écrit un petit exemple en C# qui fait cela:
Mon exemple de code peut être optimisé en outre. De nombreuses chaînes de la mise en cache sont des doublons, et certains sont des doublons avec juste un personnage supplémentaire ajouté. Il utilise plus d'espace que nécessaire lors de l'entrée des chaînes de devenir grand.
Sur entrée: "666222054263314443712", "5432127413542377777", "6664664565464057425"
Le LCS retournée est "54442"
J'ai juste eu à le faire pour des devoirs à faire, alors voici ma dynamique de la solution de programmation en python qui est assez efficace. Il est O(lnm) où n, m et l sont les longueurs des trois séquences.
La solution passe par la création d'un tableau 3D et ensuite l'énumération de tous les trois séquences pour calculer le chemin de la plus longue sous-suite. Ensuite, vous pouvez revenir en arrière à travers le tableau de reconstruire le réel sous-suite de son chemin.
Donc, vous initialiser le tableau à tous les zéros, puis énumérer les trois séquences. À chaque étape de l'énumération, vous pouvez ajouter un à la longueur de la plus longue sous-suite (si il y a correspondance) ou de report de la plus longue sous-suite de l'étape précédente de l'énumération.
Une fois que l'énumération est terminée, vous pouvez maintenant remonter à travers le tableau de reconstruire la sous-suite des mesures que vous avez prises. c'est à dire comme vous le voyage à rebours à partir de la dernière entrée dans le tableau, chaque fois que vous rencontrez un match, vous rechercher dans l'une quelconque des séquences (en utilisant les coordonnées de la matrice) et l'ajouter à la sous-suite.