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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé 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
    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;
    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    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
    Membre confirmé 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
    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.

  4. #4
    Membre expérimenté

    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
    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
    Membre confirmé 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
    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.

  6. #6
    Membre confirmé 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
    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.

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 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 ;
        }

  8. #8
    Membre confirmé 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
    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 ...

  9. #9
    Membre confirmé 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
    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.

  10. #10
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 971
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 971
    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.

  11. #11
    Membre confirmé 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
    Par défaut
    Certes, mais l'énoncé est comme cela.
    Le prof doit être un vicieux

+ 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