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

C Discussion :

Calcul du nombres de lignes communes entre deux mots


Sujet :

C

  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut Calcul du nombres de lignes communes entre deux mots
    Bonjour à tous,

    Tout d'abord, le contexte.

    J'ai des Mot ( une structure ) qui contient entre autre une chaine de caractère, son nombre d'occurances ( tiens, je ne sais toujours pas écrire ce mot ), et un tableau dynamique qui contient les lignes ou apparait ce mot dans un fichier texte.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct Mot
    {
    	char* mot;	// Garde le mot
    	unsigned int nbOccurances; // Nombre d'occurance dans le fichier
    	IList lignes; // La liste des lignes ou il apparait.
    }Mot;
    ( Note: Un tableau dynamique est juste une structure qui à une taille, un pointeur, une capacité ( on ne peut pas faire beaucoup plus simple ) )

    Maintenant, j'ai deux Mot. Je veux calculer le nombre de ligne commune, entre deux Mot.
    J'utilise cette fonction:

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    /**
     * Nous avons un avantage pour ces deux fonctions
     * Le liste des lignes sera trié ( car nous lisons un fichier de haut en bas :D )
     * Ce qui fera que la recherche des lignes communes sera facilité ( en terme de calcul )
     */	
    unsigned int nbCommunes(const Mot* const mot1, const Mot* const mot2)
    {
    	// Récupération des tailles des tableaux
    	unsigned int limiteMot1 = mot1->lignes.taille;	
    	unsigned int limiteMot2 = mot2->lignes.taille;	
     
    	unsigned int compteur1 = 0;
    	unsigned int compteur2 = 0;
     
    	unsigned lignesCommunes = 0;
     
    	while ( compteur1 < limiteMot1 || compteur2 < limiteMot2 )
    	{
    		if ( mot1->lignes.tableau[compteur1] == mot2->lignes.tableau[compteur2] )
    		{
    			lignesCommunes++;
    			// On peut passer à la ligne suivante
    			compteur1++;
    			compteur2++;
     
    			// Si on matche le dernier mot ... on a pas besoin de continuer ( principe d'unicité des elements )
    			if ( compteur1 >= limiteMot1 )
    			{
    				break;
    			}
    			if ( compteur2 >= limiteMot2 )
    			{
    				break;
    			}
    		}
    		else if ( mot1->lignes.tableau[compteur1] < mot2->lignes.tableau[compteur2] )
    		{
    			if ( compteur1 < limiteMot1 - 1 ) // -1 pour pouvoir continuer à utiliser l'élément courant
    			{
    				compteur1++;
    			}
    			else
    			{
    				// Fin de la recherche
    				break;
    			}
    		}
    		else // Soit mot1.lignes.tableau[compteur1] > mot2.lignes.tableau[compteur2]
    		{
    			if ( compteur2 < limiteMot2 - 1 )	// -1 pour pouvoir continuer à utiliser l'élément
    			{
    				compteur2++;
    			}
    			else
    			{
    				// Fin de la recherche
    				break;
    			}
    		}		
    	}
     
    #ifdef _DEBUG
    	printf("(%s,%s) ont %u lignes communes\n",mot1.mot, mot2.mot, lignesCommunes);
    #endif
     
    	return lignesCommunes;
    }
    Cette fonction fonctionne ( wouhou ). Aucun bug dedans.
    Par contre, elle est super trop trop trop lente. ( Je fais facilement des millions d'appel dessus, et c'est celle qui prend le plus de temps ( c'est vérifié ) ).
    Je ne suis pas le meilleur en terme d'optimisation, ainsi donc, je demande votre aide.

    Que peut on faire pour optimiser?

    ( Sachez aussi que j'ai une fonction comparable, pour faire la même chose avec trois Mot différent. ) Bien sur, la fonction va utilisé une liste ( tableau dynamique ) pour stocker les resultats, puis refaire la comparaison avec le troisième mot. ( Vive la perte de temps ).

    Je vous remercie d'avance pour toute remarque et aide à l'amélioration de ce code.

    LittleWhite
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Mis à part des améliorations de détail du codage, je vois rien d'évident.

    Toutefois, On pourrait essayer d'optimiser ainsi :
    Lorsqu'on incrémente un seul des indices (disons compteur1++, mais on traitera compteur2++ de façon analogue), on insére l'instruction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    While (Compteur1+N<Limite1 && 
               mot1->lignes.tableau[compteur1+N] < mot2->lignes.tableau[compteur2]) 
           Compteur1=Compteur1+N ;
    Faire quelques essais pour trouver la bonne valeur de N (>10 pour un gain significatif ? en dessous de 5 , on gagnera pas grand-chose).
    Même Code amélioré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Limite1MoinsN=Limite1-N ;
    tableau1Decale= ... // caster tableauDecale sur Mot1->lignes.tableau de façon
                        //  à ce que tableauDecale[i+N]= Mot1->lignes.tableau[i]
    ...
    While (Compteur1<Limite1MoinsN && 
               tableau1Decale[compteur1] < mot2->lignes.tableau[compteur2]) 
           Compteur1+=N ;
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Points : 593
    Points
    593
    Par défaut
    Je penses pas que ca améliore grand chose mais je crois que tu peux déjà supprimer le teste du while vu que tu mets des breaks partout.

    Sinon une autre solution algorithmique pourrait être de concaténer les deux listes, les trier (elles contiennent bien des int indice de la place de la ligne dans le fichier ?), et après parcourir la liste pour trouver le nombres d'entiers identique cote à cote mais je pense pas que la complexité soit meilleur...

  4. #4
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    concaténer les deux listes, les trier
    L'algorithme initial correspond déjà au dernier pas d'un tri-fusion.

    J'aurais une solution si la plupart des documents sont petits (ordre de grandeur : moins de 200 lignes).
    Est-ce le cas ?
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  5. #5
    Débutant Avatar de étoile de mer
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    978
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 978
    Points : 117
    Points
    117
    Par défaut
    Bonjour à tous,
    Je connais le problème de LittleWhite.
    Ce sont des fichiers texte de taille de plus de 500 000 lignes

    Merci
    Le jour est le père du labeur et la nuit est la mère des pensées.

  6. #6
    Membre régulier Avatar de mikhailo
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    78
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 78
    Points : 75
    Points
    75
    Par défaut
    Je crois que etoile de mer a raison; j'ai eu un projet à faire comportant pas mal de traitement des mots et des dictionnaires (faisant 500k lignes environ), et quand j'ai abandonné le fichier texte en le transformant en un char**, le temps d'exécution est passé de 8h à 5-10 minutes.
    "Les hommes et les femmes qui, sans bouger de leur bureau ou de leur bibliotheque, sans développer leur puissance corporelle et leurs infinies dimensions, parviennent, par une opération de la conscience, à une tristesse pessimiste qui se pretend lucide ne font que constater, sans le savoir, que toute identification du multiple de la vie à la vacuite de la conscience mène inévitablement à ce pessimisme et cette impuissance."

    extrait de "La fragilité" de Benasayag

  7. #7
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    J'aurais une solution si la plupart des documents sont petits (ordre de grandeur : moins de 200 lignes).
    Non, nous avons vraiment des grands cas. Je veux dire que par là, il n'est pas rare que la recherche de lignes communes se fasse sur des grands tableaux ( plus de 1000 cases )
    J'ai pensé à faire une table de resultats, mais je ne suis pas que cela va beaucoup amélioré.

    Je pense ( et je vais bientot l'appliqué ) que le time killer, ce sont les 'break;'
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    @mikhailo: À ce point du programme, tout est déjà en RAM.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par mikhailo Voir le message
    Je crois que etoile de mer a raison; j'ai eu un projet à faire comportant pas mal de traitement des mots et des dictionnaires (faisant 500k lignes environ), et quand j'ai abandonné le fichier texte en le transformant en un char**, le temps d'exécution est passé de 8h à 5-10 minutes.
    Je suis déjà avec des fichiers en mémoire.
    Lorsque j'enlève mon nbOccurances dans la ligne de calcul, je passe facilement de 4j à 30 minutes.
    Du coup, je sais où je dois optimiser ... mais je ne suis pas trop sur du comment.

    Est ce que vous faites un algorithme du genre de celui que j'utilise, pour avoir le nombre de lignes communes, ou pas du tout? ( Car votre vitesse m'interesse )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #10
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Si les fichiers sont gros, la solution dans ma première réponse devrait améliorer les performances.
    Est ce que vous faites un algorithme du genre de celui que j'utilise, pour avoir le nombre de lignes communes, ou pas du tout? ( Car votre vitesse m'interesse )
    Quel est l'objectif recherché ?
    Si il s'agit de detection de co-occurences (couples de mots voisins) dans un comparateur de document, on peut limiter la comparaison aux documents suffisament proches hors utilisation des co-occurences et utiliser les co-occurences seulement sur ce sous-ensemble de documents "proches".
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  11. #11
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Graffito Voir le message
    Si les fichiers sont gros, la solution dans ma première réponse devrait améliorer les performances.

    Quel est l'objectif recherché ?
    Si il s'agit de detection de co-occurences (couples de mots voisins) dans un comparateur de document, on peut limiter la comparaison aux documents suffisament proches hors utilisation des co-occurences et utiliser les co-occurences seulement sur ce sous-ensemble de documents "proches".
    Objectif recherché, bah ... savoir le nombre de ligne commune entre deux mots ... et ce pour tout les mots du fichiers. Il n'y a pas de co-occurences spécifique, car on se base sur une similarité entre deux fichiers ...
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Points : 593
    Points
    593
    Par défaut
    Bien sûr le programme ne tourne pas sur une machine multi-coeurs ?

  13. #13
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Bien sûr le programme ne tourne pas sur une machine multi-coeurs ?
    Pas toujours ....
    Mais on pourrait ( enfin je ) lancé un deuxième thread ...
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  14. #14
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Graffito Voir le message
    Mis à part des améliorations de détail du codage, je vois rien d'évident.

    Toutefois, On pourrait essayer d'optimiser ainsi :
    Lorsqu'on incrémente un seul des indices (disons compteur1++, mais on traitera compteur2++ de façon analogue), on insére l'instruction suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    While (Compteur1+N<Limite1 && 
               mot1->lignes.tableau[compteur1+N] < mot2->lignes.tableau[compteur2]) 
           Compteur1=Compteur1+N ;
    Faire quelques essais pour trouver la bonne valeur de N (>10 pour un gain significatif ? en dessous de 5 , on gagnera pas grand-chose).
    Même Code amélioré:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Limite1MoinsN=Limite1-N ;
    tableau1Decale= ... // caster tableauDecale sur Mot1->lignes.tableau de façon
                        //  à ce que tableauDecale[i+N]= Mot1->lignes.tableau[i]
    ...
    While (Compteur1<Limite1MoinsN && 
               tableau1Decale[compteur1] < mot2->lignes.tableau[compteur2]) 
           Compteur1+=N ;
    Je suis bien désolé, mais je n'ai pas compris cette histoire d'indice N.
    Pouvez vous expliquer, de façon très très claire.
    Pour moi il semble que vous loupez des valeurs avec cette histoire de N...
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  15. #15
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Je pense que le plus simple est d'agir en amont de ta fonction. Si tu as un tableau de Mot, tu les tries par ordre alphabétique, comme ça tu auras un temps beaucoup plus linéaire au moment de la comparaison.
    Qu'est-ce que tu utilises comme structure de données pour stocker tes Mot ?
    Plus tu pédales moins fort, moins t'avances plus vite.

  16. #16
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Pouet_forever Voir le message
    Je pense que le plus simple est d'agir en amont de ta fonction. Si tu as un tableau de Mot, tu les tries par ordre alphabétique, comme ça tu auras un temps beaucoup plus linéaire au moment de la comparaison.
    Qu'est-ce que tu utilises comme structure de données pour stocker tes Mot ?
    Je n'ai pas besoin de faire un tri alphabétique. Je ne vois pas en quoi cela me servirai ( pour le nombre de lignes communes des mots ).
    Pour accéder aux Mot, j'utilise une table de hachage.
    Pour savoir l'ordre des mots, j'ai un système qui reproduit virtuellement le fichier.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  17. #17
    Membre éclairé
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Points : 842
    Points
    842
    Par défaut
    Mea culpa, j'ai mal lu.
    Plus tu pédales moins fort, moins t'avances plus vite.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Points : 593
    Points
    593
    Par défaut
    Grossièrement la technique de Graffito (qui est surement la meilleur idée) est de voir si on ne peut pas avancer de N en N au lieu de parcourir la liste de 1 en 1. Comme la liste est triée par ordre de croissant on ne peut pas sauter de ligne intéressante.

  19. #19
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Grossièrement la technique de Graffito (qui est surement la meilleur idée) est de voir si on ne peut pas avancer de N en N au lieu de parcourir la liste de 1 en 1. Comme la liste est triée par ordre de croissant on ne peut pas sauter de ligne intéressante.
    Je vois, mais en fait, je ne vois pas comment on fait pour ne pas se louper, en faisant cette technique.
    Je veux dire, je veux bien avancé de deux par deux ... mais comment je ne loupe pas une ligne ( je vais tenter un truc tout de suite ) ... mais je reste perplexe.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Points : 593
    Points
    593
    Par défaut
    A force de bricolage je t'ai pondu ça :

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    const int N = 10;
     
    unsigned int nbCommunes(const Mot* const mot1, const Mot* const mot2)
    {
    	// Récupération des tailles des tableaux
    	unsigned int limiteMot1 = mot1->lignes.taille;	
    	unsigned int limiteMot2 = mot2->lignes.taille;	
     
    	unsigned int limiteMot1MoinsN =	limiteMot1-N;
    	unsigned int limiteMot2MoinsN =	limiteMot2-N;
     
    	unsigned int compteur1 = 0;
    	unsigned int compteur2 = 0;
     
    	unsigned lignesCommunes = 0;
     
    	while((mot1->lignes.tableau[compteur1] < mot2->lignes.tableau[compteur2] && compteur1 < limiteMot1 - 1 ) &&
    		(mot1->lignes.tableau[compteur1] > mot2->lignes.tableau[compteur2] && compteur2 < limiteMot2 - 1 ))
    	{
    		while(mot1->lignes.tableau[compteur1] < mot2->lignes.tableau[compteur2] && compteur1 < limiteMot1 - 1 )
    				if( compteur1 < limiteMot1MoinsN && mot1->lignes.tableau[compteur1+N] < mot2->lignes.tableau[compteur2])
    					compteur1+=N;
    				else 
    					compteur1++;
     
     
    		while(mot1->lignes.tableau[compteur1] > mot2->lignes.tableau[compteur2]] && compteu2 < limiteMot2 - 1 )
    				if( compteur2 < limiteMot2MoinsN && mot1->lignes.tableau[compteur1] > mot2->lignes.tableau[compteur2+N])
    					compteur2+=N;
    				else 
    					compteur2++;
     
     
    		if( mot1->lignes.tableau[compteur1] == mot2->lignes.tableau[compteur2] )
    		{
    			lignesCommunes++;
    			// On peut passer à la ligne suivante
    			compteur1++;
    			compteur2++;
     
    			// Si on matche le dernier mot ... on a pas besoin de continuer ( principe d'unicité des elements )
    			if ( compteur1 >= limiteMot1 )
    			{
    				break;
    			}
    			if ( compteur2 >= limiteMot2 )
    			{
    				break;
    			}
     
    		}
     
     
    	}
     
    	return lignesCommunes;
    }

    J'aime bien les gros testes qui tâches.

    Pour trouver le meilleur N il faudrait peut-être connaître la valeur moyenne de (lignesCommunes / le nombre de ligne).

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Nombre d'éléments communs entre deux tableaux
    Par momo-mtl dans le forum Général JavaScript
    Réponses: 16
    Dernier message: 19/02/2015, 10h08
  2. Calcul de nombre de jours ouvrable entre deux date
    Par etienneborms dans le forum Débuter
    Réponses: 6
    Dernier message: 30/01/2012, 10h53
  3. Réponses: 7
    Dernier message: 16/12/2009, 14h10
  4. Réponses: 1
    Dernier message: 10/08/2006, 14h43
  5. Réponses: 15
    Dernier message: 17/06/2006, 11h49

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