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 :

Trier par ordre alphabétique des chaînes de caractères


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Trier par ordre alphabétique des chaînes de caractères
    Bonjour à tous, je suis nouveau ici, je me suis inscris il y a peu! je fréquentais de temps en temps le forum afin de trouver des réponses sur certains de mes problèmes.

    Il est évident que je ne cherche pas une réponse qui fera le boulot à ma place mais plutôt une orientation vers la bonne solution.

    Ici, je viens à vous afin de trouver une solution à un problème dont je vais vous exposez le code mais avant des explications s'impose.

    C'est un projet que je dois réaliser pour première année bachelier (Belgique), je dois le rendre pour la fin des vacances, tout est terminé sauf un dernier traitement que je dois effectuer.

    Avant que vous voyez le code et que vous vous demandez pourquoi j'ai fais comme ça et pas comme ça, voici les conditions du professeur:

    1. Utilisation de tableau à deux dimension
    2. pas de (pointeur) pas exactement mais une façon est décrite pour passer en paramètre un tableau
    3. Toutes fonction d'une bibliothèque doit être réaliser par moi même
    4. ne pas être tenter à utiliser les pointeurs(ce qui serait plus simple)

    Sachez que ce projet consiste à enregistrer des clients(prénom) dans un tableau de N dimension et les afficher par la suite en ordre alphabétique voilà pourquoi il faut utiliser un tableau à deux dimension.

    Vous devez savoir que j'ai réalisé cette partie du code à pars du projet afin de la tester proprement et pour mieux m'y retrouver, une fois bien en fonction je l'intègrerai dans le reste du code.

    Mon problème est que le tri ne s'effectue pas correctement et je ne trouve pas la solution en plus je travaille comme un malade la journée et je n'ai que mes soirée pour bosser dessus! (cours du soir) un petit coup de pouce ça serait le bienvenue.

    Je vous remercie d'avance, j'espère que les explications on été clair!

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int strcomp(char tab[][31],int i);
    void tri_bulle(char tri[][31]);
    int compteur_caractere(char tri[][31],int i);
     
    int main()
    {
        int i,j;
        char tab[5][31];
        char tri[5][31];
     
     
        for(i=0;i<4;i++)
        {
            printf("\nEntrez un mot:");
            gets(tab[i]);
        }
     
     
     
        //Copie Tab dans tri
        for(i=0;i<4;i++)
        {
            for(j=0;j<=compteur_caractere(tab,i);j++)
                tri[i][j]=tab[i][j];
        }
     
     
        printf("\n\n\n\n");
        //affiche le tableau tab
        for(i=0;i<4;i++)
        {
            printf("%s\n",tab[i]);
        }
     
     
        tri_bulle(tri);
        printf("\n\n\n\n");
     
     
     
        //affiche le tableau tri
        for(i=0;i<4;i++)
        {
            printf("%s\n",tri[i]);
        }
     
        return 0;
    }
     
    int strcomp(char tab[][31],int i)
    {
        int j=0;
     
        while(tab[i][j] != '\0' && tab[i+1][j] != '\0')
        {
            if (tab[i][j] != tab[i+1][j])
            {
                if (tab[i][j] > tab[i+1][j])
                    return (1);
                if (tab[i][j] < tab[i+1][j])
                    return (-1);
            }
            j++;
        }
        return (0);
     
    }
     
    void tri_bulle(char tri[][31])
    {
        int i,a,j;
        int parcours;
        char tempon[31];
        parcours=3;
     
        for(a=0;a<parcours;a++)
        {
            for(i=0;i<3;i++)
            {
     
                if(strcomp(tri,i)==1)
                {
                    for(j=0;tempon[j]=='\0';++j)
                    {
                        tempon[j]=tri[i][j];
                    }
                    for(j=0;tri[i][j]!='\0';j++)
                    {
                        tri[i][j]=tri[i+1][j];
                    }
     
                    for(j=0;tri[i+1][j]!='\0';j++)
                    {
                        tri[i+1][j]=tempon[j];
                    }
                }
            }
            parcours--;
        }
    }
    int compteur_caractere(char tri[][31],int i)
    {
        int j=0; // est le numéro de cellule
     
            while (tri[i][j]!='\0')
            {
                j++;
            }
     
        return j;
     
    }

  2. #2
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Quelques conseils sur ton code :

    1- Même si tu n'as pas le droit d'utiliser les fonctions standard de manipulation de chaines, tu peux les réécrire en t'inspirant de leur prototype. Par exemple, pour trouver le nombre d'éléments d'une chaine (l'équivalent de strlen()) il suffit d'avoir en argument l'adresse de départ de la chaine et non pas un char [][31]
    En utilisant ton code et en l'adaptant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int compteur_caractere(char chaine[])
    {
       int j=0; // est le numéro de cellule
       while (chaine[j]!='\0')
       {
         j++;
       }
       return j;
    }
    De la même façon, ta fonction strcomp() compare deux chaines successives dans le tableau des chaines. C'est une source possible d'un problème masqué si i correspond à la dernière chaine du tableau.
    Je pense qu'il vaut mieux réécrire la comparaison de deux chaines :
    int strcomp( char *chaine1, char * chaine2)
    Il est alors explicitement de la responsabilité directe de l'utilisateur de s'assurer que les deux chaines existent.
    A noter que les paramètres du prototype en char * sont équivalents à char[]. Quand on écrit char[] comme paramètre, le compilateur traduit en char *. Cela n'implique pas plus l'utilisation de pointeur (de toute façon, ce sera un pointeur dans les deux cas)
    En adaptant ton code :
    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 strcomp(char * chaine1,char *chaine2)
    {
     int j=0;
     while(chaine1[j] != '\0' && chaine2[j] != '\0')
     {
        if (chaine1[j] != chaine2[j])
        {
          if (chaine1[j] > chaine2[j]) return (1);
          if (chaine1[j] < chaine2[j]) return (-1);
        }
        j++;
     }
     return (0);
    }
    2- Pour des questions de clarté dans la fonction de tri, il peut être avantageux d'écrire une fonction qui échange le contenu de deux chaines de caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void strechange( char * chaine1 , char * chaine2)
    Cela peut se faire sans tableau tampon en procédant caractère par caractère donc de façon très générale (mais suppose évidemment que la place allouée aux tableaux chaine1 et chaine2 permet cet échange) .
    ta fonction tri est alors très simple et semble correcte (mis à part le nombre magique 3 : parcours devrait être un paramètre de la fonction ; elle peut être améliorée en arrêtant si dans un passage aucune permutation n'a lieu) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void tri_bulle(char tri[][31])
    {
        int i,a;
        int parcours = 3;
        for(a=0;a<parcours;a++)
        {
            for(i=0;i<3;i++)
            {
                if(strcomp(tri[i],tri[i+1])==1) strechange(tri[i],tri[i+1]);
            }
            parcours--;
        }
    }
    3- Ne pas utiliser gets() qui est une fonction déclassée mais préférer fgets(). Par contre, fgets() conserve le '\n' qu'il faut éliminer ce qui est une légère complication si on n'a pas accès à strchr(). Mais si on suppose que la ligne ne sera pas plus grande que le buffer de réception, c'est facile. Il peut être utile d'écrire l'équivalent de strcpy() pour clarifier le main.

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Je te remercie beaucoup pour ta réponse bien complète qui m'a très bien aidé. J'ai bientot fini dans mon travail,

    Dès que j'ai fini je mettrai le code à disposition de tout le monde et tu pourrai commenter ce que j'ai codé!

    Merci encore

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par diogene Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int strcomp(char * chaine1,char *chaine2)
    {
     int j=0;
     while(chaine1[j] != '\0' && chaine2[j] != '\0')
     {
        if (chaine1[j] != chaine2[j])
        {
          if (chaine1[j] > chaine2[j]) return (1);
          if (chaine1[j] < chaine2[j]) return (-1);
        }
        j++;
     }
     return (0);
    Bonjour

    Ce test est-il réellement utile ???
    De plus, me semble que si une des chaines est plus courte que l'autre, l'un des deux tests du while sera faux ce qui amènera à sauter la boucle et à retourner 0 ce qui n'est pas en accord avec le fonctionnement du strcmp() d'origine...

  5. #5
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Tu as raison, mais je ne voulais pas réécrire ni discuter le code de la fonction.
    Comme je conseillais de changer son prototype, pour montrer au PO l'incidence de ce changement sur son code, je l'ai repris simplement en l'adaptant pour tenir compte de ce changement.

    Je pense qu'il vaut mieux réécrire la comparaison de deux chaines :
    int strcomp( char *chaine1, char * chaine2)
    ....
    En adaptant ton code :....

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Yop!

    voilà j'ai changé le code la fonction de comparaison d'une chaine et j'ai pris exemple sur un exemple que j'ai trouvé sur mon pote google!

    voilà ...
    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
    int strcomp(char *chaine_un,char *chaine_deux)
    {
        int i,valeur;
     
        for(i=0;chaine_un[i]==chaine_deux[i];i++)
            if (chaine_un[i]=='\0')
                valeur=0;
     
        valeur=chaine_un[i]-chaine_deux[i];
     
        if(valeur>1)valeur=1;
        else if(valeur<0) valeur=-1;
     
        return valeur;
    }
    Je suis obligé de retourner une valeur -1, 0 et 1 selon les consignes du professeur.
    Ainsi de cette manière je fais une soustraction des caractères qui ne sont pas égaux(boucle for) afin de retourner un positif ou un négatif et si c'est positif je remet ça sur 1 et si c'est négatif sur -1 si c'est le contraire.

    consignes respectées.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 721
    Points : 31 044
    Points
    31 044
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nyzos Voir le message
    Yop!

    voilà j'ai changé le code la fonction de comparaison d'une chaine et j'ai pris exemple sur un exemple que j'ai trouvé sur mon pote google!

    voilà ...
    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
    int strcomp(char *chaine_un,char *chaine_deux)
    {
        int i,valeur;
     
        for(i=0;chaine_un[i]==chaine_deux[i];i++)
            if (chaine_un[i]=='\0')
                valeur=0;
     
        valeur=chaine_un[i]-chaine_deux[i];
     
        if(valeur>1)valeur=1;
        else if(valeur<0) valeur=-1;
     
        return valeur;
    }
    Je suis obligé de retourner une valeur -1, 0 et 1 selon les consignes du professeur.
    Ainsi de cette manière je fais une soustraction des caractères qui ne sont pas égaux(boucle for) afin de retourner un positif ou un négatif et si c'est positif je remet ça sur 1 et si c'est négatif sur -1 si c'est le contraire.

    consignes respectées.
    Mouais. Tu as remarqué que tout ton code de travail se trouve en dehors de la boucle for ???
    Tu aurais pris exemple sur ta propre logique et ton propre cerveau, tu aurais fait plus simple et plus réussi

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int strcomp(char *chaine_un,char *chaine_deux)
    {
        int i;
     
        for(i=0; chaine_un[i] != '\0' || chaine_deux[i] != '\0'; i++)
        {
            if (chaine_un[i] < chaine_deux[i])
               return -1;
            if (chaine_un[i] > chaine_deux[i])
               return 1;
        }
        return 0;
    }

    Il n'y a pas que de bons trucs sur google...

Discussions similaires

  1. Trier par ordre alphabétique des onglets d'une certaine couleur
    Par shimuno dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 03/10/2011, 17h54
  2. Réponses: 11
    Dernier message: 28/06/2010, 11h16
  3. Réponses: 7
    Dernier message: 13/09/2007, 15h22
  4. Trier par ordre alphabétique un tableau
    Par barbiche dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 09/03/2007, 17h15
  5. Réponses: 1
    Dernier message: 27/05/2006, 23h13

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