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 :

Erreur de recherche dichotomique


Sujet :

C

  1. #1
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut Erreur de recherche dichotomique
    Bonjour à tous,

    Ma fonction de recherche dichotomique ne fonctionne pas et je ne trouve pas l'origine du mal. Le dico est trié correctement avec qsort() au préalable (merci E.D.). Pourriez-vous m'éclairer ? Merci d'avance.

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #include<ctype.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    /*  
        Fonction de recherche dichotomique.
    */
     
    int dichotomie(char dico[][LONG_MOT], char mot[], int nbMots)
    {
        int i = 0;   /* Indice de debut.  */
        int j = nbMots;   /* Indice de fin.  */
        int k = 0;   /*  Indice de milieu.  */
        int trouve = 0;   /*  Boleenne (faux si pas trouve.)  */  
     
        while (!trouve && ((j - i) > 1) )
        {				
             k = (i + j) / 2;
             if (strcmp (dico[k], mot) == 0) 
                 trouve = 1;
     
             if (strcmp (dico[k], mot) > 0)
    	         j = k ;
             else
    	         i = k ;
        }
     
        if (dico[i] == mot)
            return (i);  
        else
            return (-1);  
    }
     
    int main (int argc, char *argv[])
    {
        FILE *fiDico = fopen ("dico.dat", "r");
        ret = EXIT_SUCCESS ;
        int nbMots = 0;   /*  Valeur pour le nombre de mots.  */ 
        int resultat;   /*  Retour de la fonction.  */
        char ligne[LONG_MOT] = " ";   /*  Stockage des lignes des fichiers.  */
        char dico[MAX_MOTS][LONG_MOT] = { " " }; /* Dico.  */
        char mot[26] = " " ;   /*  Mot a rechercher.  */
     
        if (fiDico != NULL)
        {
            /*  Lecture du fichier et stokage dans le tableau "dico".  */
            while (nbMots < MAX_MOTS && fgets (ligne, LONG_MOT, fiDico) != NULL)
                {
                    strcpy (dico[nbMots], ligne);
                    nbMots++;
                }
            fclose (fiDico);
            fiDico = NULL;
     
            fputs ("\nTapez  le mot a rechercher dans le dictionnaire : ", stdout);
            fflush (stdout);
            fgets (mot, sizeof mot, stdin);    
            if (mot[strlen(mot) - 1]  == '\n')
                mot[strlen(mot) - 1] = '\0';  
     
            /* Recherche  dans dico.  */   
            resultat = dichotomie (dico, mot, nbMots); 
            if (resultat != -1)
            {
    	    fprintf (stdout, "Ce mot se trouve déjà en position %d du dico.\n", resultat);
            }
            else
            {
                fprintf (stdout, "Ce mot n'est pas dans le dictionnaire!\n");    
            }
        }
        else
        {
            printf ("Clash de \"dico.dat\".");
            ret = EXIT_FAILURE;
        }
     
        fprintf (stdout, "Appuyez sur une touche...");
        getch ();
        return ret;
    }
    Intuitu Personae

  2. #2
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (dico[i] == mot)
            return (i);  
        else
            return (-1);
    Là, aussi, tu dois utiliser strcmp().
    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.

  3. #3
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    Affhh...Merci Médinoc .
    C'est incroyablement difficile de perdre des habitudes du genre "égal à "
    Mais corrigé c'est pareil, il ne me trouve aucun mot.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if (strcmp (dico[i], mot) == 0 )
            return (i);  
        else
            return (-1);
    J'enrage de pas voir.
    Intuitu Personae

  4. #4
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 242
    Points : 354
    Points
    354
    Par défaut
    Je pense que ton erreur vient de ta condition d'arrêt de ta boucle while.
    As-tu essayé par exemple, de mettre un ">=" plutôt qu'un ">" ?

    Sinon, la meilleure chose à faire, et qui te sera plus profitable que si on te donne la solution comme cela, c'est de faire des affichages (printf..). Utilise un petit fichier source qui pose problème et affiche les numeros de tes indices de début et fin i et j systématiquement. Essaie de faire l'algorithme aussi à la main, et cherche les différences. Tu devrais rapidement trouvé la solution sur une petite fonction comme celle-ci... Bon courage

  5. #5
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    Merci Climoo mais hélas ce n'est pas cela.
    La comparaison est peut-être fausse en raison d'un '\n' ou autre chose du même genre. Mais là non plus, je séche.
    Intuitu Personae

  6. #6
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    En vérifiant cette histoire de retour chariot j'ai oté la condition suivante après le fgets () :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (mot[strlen(mot) - 1]  == '\n')
        mot[strlen(mot) - 1] = '\0';
    Maintenant il trouve le premier mot de mon dico mais seulement celui-là.
    Il faut maintenant trouver la logique de l'histoire et corriger pour l'ensemble.
    Intuitu Personae

  7. #7
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Salut,

    Citation Envoyé par stallaf Voir le message
    En vérifiant cette histoire de retour chariot j'ai oté la condition suivante après le fgets () :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (mot[strlen(mot) - 1]  == '\n')
        mot[strlen(mot) - 1] = '\0';
    Maintenant il trouve le premier mot de mon dico mais seulement celui-là.
    Il faut maintenant trouver la logique de l'histoire et corriger pour l'ensemble.
    Bon il faut se mettre d'accord soit tu enlèves les retours chariots mais, partout soit tu les laisses tranquille et les comparaisons se feront tout aussi bien ...parce que la tu n'enlevais que le '\n' des mots saisies par l'utilisateur pas ceux lus à partir du fichier ...

    Pour ce qui est de ta fonction de recherche je pense que c'est clair tu utilises une booléenne dont le nom est assez explicite 'trouve' il est logique que le test pour savoir si le mot a été trouvé ou pas soit fait sur cette variable non ? sinon le 'k' n'est pas l'indice du mot mais, celui de la borne supérieure
    To start press any key. (reading screen) Where's the "any" key? I see Esc, Catarl, and Pig Up. There doesn't seem to be any "any" key. Wo! All this computer hacking is making me thirsty. I think I'll order a Tab. (presses TAB key). -- HOMER --

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Voici un exemple de recherche dicotomique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    int rechDichIt(int valRech, int tabEnt[], int taille)
    {
         int deb = 0, fin = taille -1, mil;
     
         while (deb <= fin)
         {
        mil = (deb+fin)/2;
        if (valRech ==  tabEnt[mil]) return mil;
        if (valRech < tabEnt[mil]) fin = mil-1;
        else                       deb = mil+1;
         }
         return(-1);
    }
    Quand tu met à jour la position de début et de fin , il faut faire fin = mil-1 et deb = mil+1. Pour ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
         while (!trouve && ((j - i) > 1) )
        {                
             k = (i + j) / 2;
             if (strcmp (dico[k], mot) == 0) 
                 trouve = 1;
     
             if (strcmp (dico[k], mot) > 0)
                 j = k-1 ;
             else
                 i = k+1 ;
        }

  9. #9
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    Je ne pense pas qu'ajouter ou retrancher 1 aux bornes soit la source de mes problèmes; On gagne en effet en efficacité puisque la nouvelle borne devient le milieu plus ou moins 1. Ok je l'adopte.
    J'ai encore un problème de compréhension globale : manque-t-il une boucle ...
    Intuitu Personae

  10. #10
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    Résolu :

    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
    int dichotomie(char dico[][LONG_MOT], char mot[], int nbMots)
    {
        int i = 0;              /* Indice de debut.  */
        int j = nbMots;         /* Indice de fin.  */
        int k = 0;              /*  Indice de milieu.  */
        int trouve = 1 ;		/*  Boleenne valant 1 (faux) tant que mot n'est pas trouve.  */  
     
        while ( (trouve == 1) && (i <= j) )
        {				
             k = (i + j) / 2;
             if (strcmp (dico[k], mot) == 0) 
                 trouve = 0;
             if (strcmp (dico[k], mot) > 0)
                 j = k - 1;
             else
    	     i = k + 1; 
        }
        if (trouve == 0)
            return (i );
        else
            return (-1);  
    }
    Les conditions du while se portent bien mieux comme cela.
    Merci pour votre aide.
    Intuitu Personae

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Gao,
    Citation Envoyé par stallaf Voir le message
    Résolu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ...
        int trouve = 1 ;		/*  Boleenne valant 1 (faux) tant que mot n'est pas trouve.*/
    ...
    Normalement, 0 ==> false, et toute valeur <> 0 ==> true.
    Si les cons volaient, il ferait nuit à midi.

  12. #12
    Nouveau membre du Club Avatar de stallaf
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 79
    Points : 39
    Points
    39
    Par défaut
    Certes, mais l'énoncé est comme cela.
    Le prof doit être un vicieux
    Intuitu Personae

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme : recherche dichotomique
    Par M.a.n.u. dans le forum C
    Réponses: 3
    Dernier message: 17/06/2006, 23h30
  2. recherche dichotomique sur chaînes de carctères
    Par contexte dans le forum Langage
    Réponses: 4
    Dernier message: 13/04/2006, 00h31
  3. Réponses: 23
    Dernier message: 10/01/2006, 13h33
  4. Recherche dichotomique
    Par remixtech dans le forum C
    Réponses: 4
    Dernier message: 06/01/2006, 18h39
  5. Recherche dichotomique
    Par Gryzzly dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 31/12/2005, 11h21

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