IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Algorithme de plus grand sous-mot commun


Sujet :

Algorithmes et structures de données

  1. #1
    Membre habitué Avatar de nicolas66
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    326
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 326
    Points : 146
    Points
    146
    Par défaut Algorithme de plus grand sous-mot commun
    Bonjour,

    Pour les besoins d'un projet, j'aimerai trouver un algorithme donnait le plus grand sous-mot commun à deux chaînes de même longueur.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Chaine1 = "toto_va_bien"
    Chaine2 = "les_bielles!"
    Resultat -> "_bie"
    Quelqu'un aurait-il une idée sur l'algorithme à écrire ? Merci d'avance.


    Nico.
    Athlon 6000+ Dual Core & GeForce 8600 GT -- Ubuntu Gutsy

  2. #2
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    711
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 711
    Points : 751
    Points
    751
    Par défaut
    il y a l'algorithme "naif" qui consiste a parcourir les chaines butalement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    une chaine a de longueur n
    une chaine b de longueur m
     
    Sortie S = chaine vide
     
    de i=1 a n
       de j=1 a m
          si a[i]=b[j]
             R=a[i]
             k=i+1
             tant que a[k]=b[k]
                R=R.a[k]
                k=k+1
             fin tant que
             si longueur de S < longuer de R
                S=R
             fin si 
          fin si
       fin de
    fin de
    a la louche, c'est peut etre bien du O(mn), mais surement un peu plus. on devrait pouvoir affiner : si on trouve un mot commun, on a parcouru cerain caracteres de b, et donc ca ne sert a rien de repartir a b[j+1], mais peut etre bien a b[j+k], ou un truc du genre..

  3. #3
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  4. #4
    Membre habitué Avatar de nicolas66
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    326
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 326
    Points : 146
    Points
    146
    Par défaut
    Après avoir testé l'algorithme de jobherzt, je me suis aperçu qu'il ne fonctionnait pas correctement. En réfléchissant un tantinet, je l'ai légèrement modifié pour arriver à cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    procedure PlusGrandSousMot( Chaine ch1, Chaine ch2 ) : Chaine
    début_procedure
    	Chaine résultat, tmp
    	Entier longueur_ch1 = ch1.longueur()
    	Entier longueur_ch1 = ch2.longueur()
    	Entier i, j, k1, k2
     
    	Pour i de 1 à longueur_ch1
    	début
    		Pour j de 1 à longueur_ch2
    		début
    			Si ch1[i] = ch2[j] alors
    			début
    				tmp = ch1[i]
    				k1 = i + 1
    				k2 = j + 1
     
    				Tant_que k1 < longueur_ch1 et k2 < longueur_ch2 et ch1[k1] = ch2[k2]
    				début
    					tmp = tmp + ch1[k1]
    					k1++
    					k2++
    				fin
     
    				Si résultat.longueur() < tmp.longueur() alors
                                    début
    					résultat = tmp
                                    fin
    			fin
    		fin
    	fin
     
    	Returner résultat
    fin_procedure
    Cette fois-ci tout a l'air de fonctionner correctement. Il ne me reste plus qu'à paralléliser l'algorithme. Merci beaucoup pour votre aide


    Nico.
    Athlon 6000+ Dual Core & GeForce 8600 GT -- Ubuntu Gutsy

  5. #5
    Membre habitué Avatar de nicolas66
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    326
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 326
    Points : 146
    Points
    146
    Par défaut
    Juste une dernière question : est-ce que vous avez une idée de la complexité exacte de l'algo que je viens d'écrire ? En fait je n'arrive pas à déterminer la complexité de la boucle while. Ce qui est certain c'est que la complexité est déjà supérieure à O(n * m).
    Athlon 6000+ Dual Core & GeForce 8600 GT -- Ubuntu Gutsy

  6. #6
    Membre habitué Avatar de nicolas66
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    326
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 326
    Points : 146
    Points
    146
    Par défaut
    Personne n'a d'idée sur la complexité de l'algo ?
    Athlon 6000+ Dual Core & GeForce 8600 GT -- Ubuntu Gutsy

  7. #7
    Membre éclairé
    Inscrit en
    Janvier 2005
    Messages
    711
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 711
    Points : 751
    Points
    751
    Par défaut
    oui, exact, j'utilisais le meme indice pour les 2 chaines... ce n'etait pas a prendre au pied de la lettre. mais le lien que te fournis Jean-Marc.Bourguet donne des solutions bien plus performantes.

    pour ce qui est de la complexité, je dirais, en l'etat O(m.n.max(m,n)). mais comme je te le disais on peut l'ameliorer assea facilement en jouant sr les indices pour ne pas refaire 2 fois la meme chose. mais encore une fois, ca n'etait qu'une solution improvisée pour avoir un point de depart, il y a des solutions simples bien plus efficaces.

Discussions similaires

  1. Trouver la plus grande sous-matrice carrée unité
    Par AJMont dans le forum Mathématiques
    Réponses: 5
    Dernier message: 11/11/2014, 14h52
  2. Algorithme plus longue sous-sequence commune
    Par milfrousse dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 05/06/2014, 10h16
  3. Plus grandes sous-chaînes communes à deux chaînes
    Par steckdenis dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 20/01/2010, 14h38
  4. plus courte sous suite commune
    Par biba1980 dans le forum Algorithmes et structures de données
    Réponses: 11
    Dernier message: 30/11/2009, 22h00
  5. quel algorithme pour trouver le plus grand sous arbres commun à des arbres?
    Par iwky911 dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 20/05/2009, 21h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo