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 :

tri des chaines de charactères


Sujet :

C

  1. #1
    En attente de confirmation mail
    Inscrit en
    Octobre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 21
    Points : 8
    Points
    8
    Par défaut tri des chaines de charactères
    salut tous le monde.
    pouvez vous me donner un coup de help, je veux faire une fonction qui effectue le tri alphabétique des noms des étudients d'une classe...
    j'arrive pas à mieux améliorer ce code alors qu'il affiche n'importe quoi une fois compilé sous l'IDE Code::Blocks.

    voici le code que j'y suis abouti:
    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
     
    #include <stdio.h>
    #include <string.h>
    #define Etudient struct Etudient
     
    Etudient{
                    char Nom[20];
                    int NI;
                    char Groupe[2];
                };
     
    void permuter(char *a, char *b)
         {
             char tmp[20]={0};
             strcpy(tmp,a);
             strcpy(a,b);
             strcpy(b,tmp);
         }
     
     
    void tri_croissant(Etudient *V, int n)
         {
             int i=0,j=0,k=1,a=0,b=0;
                }
             for(i=0;i<18;i++)
                {
                    while(k<n)
                         {
                             for(j=0;j<n-k;j++)
                                {
                                    a=V[j].Nom[i];
                                    b=V[j+1].Nom[i];
                                    if(a>b) permuter(&V[j].Nom[i],&V[j+1].Nom[i]);
     
                                }
                            k++;
                         }
                }
         }
     
    suite du code....

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    Déjà Etudiant ne s'écrit pas Etudient mais Etudiant. Pour un étudiant, ça le fait pas trop.Je voudrai faire une remarque au sujet des intialisations inutiles. écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int i=0;
    for(i=0;i<N;i++)
    {
    /*...*/
    }
    n'est pas très cohérent ni lisible. Pareil pour l'initialisation en ligne. Force 2 sur l'échelle de Goret l'échelle de Goret.

    Sinon, je pense qu'il existe des fonctions de comparaison directes de chaînes de caractère en C, mais je ne sais pas comment elles marchent. Si tu te refuses à les utiliser, essaie de prendre en compte aussi les majuscules avec un modulo pour qu'elles renvoient la même valeur que les minuscules.

    La fonction permuter se destine bien à des pointeurs de tableau (ça existe cette expression ?) Oui oui des pointeurs sur char avec des fonctions de recopie de chaîne dedans. Pourquoi dans ce cas sert-elle dans le programme à premuter des caractères ? C'est idiot. Et pourquoi appeler le paramètre à la fonction V pour le tableau de type structuré ? Utiliser des noms de variable explicites est fortement recommandé. Sinon, c'est un algorithme de triage de tableau. Pourquoi est ce que la taille du tableau Etudient.nom est 20 par définition de la structure, et dans la boucle for on voit i<18 ? Ça n'a pas de sens. Je ne suis pas sûr que l'algorithme de tri fonctionne.
    un algorithme de tri ce serait quelque chose comme ç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
     
    void tri_tableau(short * tableau, short taille_tableau)
    {
    short i, k;
    for(i=0;i<taille_tableau;i++)
       {
       k=i+1;
       while(k<taille_tableau)
           {
           if(tableau[k]<tableau[i])
             {
             permute(tableau[k],tableau[i]);
             }
             k++;
          }
       }
    }
    ( Enfin j'ai tapé ce code et il ne marche pas si quelqu'un pouvait m'expliquer pourquoi au passage J'ai honte de le poster en effet, mais il me semble correct et je ne sais pas pourquoi ça n'a aucun effet. )

    EDIT : c'est ma fonction de premutation qui ne fonctionnait pas

    Avec comme comparaison entre inférieur et supérieur une fonction de comparaison de chaîne qui renvoie 1 ou 0 suivant les cas et pour tableau, il s'agit en fait de ton V[] tableau de Etudient.

  3. #3
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    N'oublie pas que la fonction qsort est ton ami.Elle permet d'effectuer ce genre de tri.
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  4. #4
    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
    De plus, ton tri ne trie pas les étudiants eux-mêmes, mais seulement leurs noms...
    Dans compter qu'il pourrait être plus intéressant d'utiliser une fonction de comparaison de chaîne plutôt que de trier caractère par caractère : Tu risques de faire plus de permutations ainsi.
    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.

  5. #5
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kromartien
    +1 pour les remarques

    ( Enfin j'ai tapé ce code et il ne marche pas si quelqu'un pouvait m'expliquer pourquoi au passage J'ai honte de le poster en effet, mais il me semble correct et je ne sais pas pourquoi ça n'a aucun effet. )
    En général, pour un tric, ce serait plutôt :

    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
     
    void tri_tableau(short * tableau, short taille_tableau)
    {
    int i, NotFinished=1;
     
    while ( NotFinished )
      {
         NotFinished = 0 ;
     
        for(i=1;i<taille_tableau;i++ )
          {
            if(tableau[i]<tableau[i-1])
             {
                permute(tableau[i],tableau[i-1]);
                NotFinished = 1 ;
                break ;
             }
           }
       }
    }
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Points : 1 111
    Points
    1 111
    Par défaut
    Oui mais utiliser break c'est mal paraît-il.

    Est ce que ces deux fonctions sont du tri par insertion ?

  7. #7
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Citation Envoyé par kromartien
    Oui mais utiliser break c'est mal paraît-il.
    Pourquoi ? Non break te fait sortir au contraire c'est trés bien je trouve
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par kromartien
    Est ce que ces deux fonctions sont du tri par insertion ?

    ouais je crois bien qu'il y a du tp dans l'air. ça vous rappelle rien
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par kromartien
    Oui mais utiliser break c'est mal paraît-il.
    Pas forcement, ca depends du contexte et de comment il est utilise.
    Ici ce n'est pas choquant, meme si personnellement je me serais plutot appuye sur la valeur de NotFinished pour sortir du for.

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gl
    Pas forcement, ca depends du contexte et de comment il est utilise.
    Ici ce n'est pas choquant, meme si personnellement je me serais plutot appuye sur la valeur de NotFinished pour sortir du for.
    d'accord avec toi, sauf pour un problème de perfomances (un test de plus à chaque fois)..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par kromartien
    Oui mais utiliser break c'est mal paraît-il.
    Mais non, c'est pas mal. C'est goto à-la-barbare (en arrière, notamment) qui est fortement déconseillé.

    break, ça va, parce que c'est un 'mini goto' vers le bas et de portée réduite (bloc de la boucle courante).

    Faut arrêter la penser binaire. Si les ordinateurs ont des bus de données de plus en plus large, c'est pour pouvoir nuancer le propos...
    Pas de Wi-Fi à la maison : CPL

  12. #12
    En attente de confirmation mail
    Inscrit en
    Octobre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 21
    Points : 8
    Points
    8
    Par défaut

    pour que vous sachiez bien de quoi je parle, voici l'enonce de l'exercice que j'essaie de resoudre..enfait j'ai deja arrive.


    exercice..::structures::..

    La liste des étudiants est représentée par un tableau de structures qu'on va allouer dynamiquement.
    Un étudiant est représenté par un enregistrement composé des champs
    -Nom : chaîne de caractères représentant le nom de l'étudiant
    -NI : entier représentant le numéro de l'étudiant
    -Groupe : caractère représentant le groupe auquel appartient cet étudiant.

    Donnez un programme pour :
    -Saisir la liste des étudiants
    -Afficher cette liste
    -Trier, dans l'ordre croissant des noms, ce tableau de structures
    -Afficher le tableau trié
    -Un étudiant veut rechercher son numéro d'inscription, pour cela, il tape au clavier son
    nom et votre programme doit afficher son nom, son numéro d'inscription et le groupe auquel il appartient.

    N.B. :
    Le programme doit définir au moins les fonctions suivantes :
    //------------------------------Prototypes de fonctions ----------------------------------
    -Void saisie (struct etudiant *V, int n);
    -Void affichage (struct etudiant *V, int n);
    -Void permuter(struct etudiant *p, struct etudiant *q);
    -Void tri_croissant(struct etudiant *V, int n);
    -Void recherche(char *nom, struct etudiant *V, int n);

    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    //-----------------Diréctives de processeur------------
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define Etudiant struct Etudiant
     
     
    //-----------------Nouveaux types----------------------
     
    Etudiant{
                    char Nom[20];
                    int NI;
                    char Groupe[2];
                };
     
     
    //------------------Prototypes--------------------------
     
    void saisie(Etudiant*,int);
    void affichage(Etudiant*,int);
    void permuter(Etudiant*,Etudiant*);
    void tri_croissant(Etudiant*,int);
    void recherche(char*,Etudiant*,int);
     
    //------------------Fonctions---------------------------
     
     
    void saisie(Etudiant *V, int n)
               {
                    int i=0;
     
                    for(i=0;i<n;i++)
                       {
                           printf("Nom de l'etudiant(e): ");
                           scanf("%s",&V[i].Nom);
                           printf("Numero: ");
                           scanf("%d",&V[i].NI);
                           printf("Groupe: ");
                           scanf("%s",&V[i].Groupe);
                            printf("\n\n");
                       }
     
               }
     
     
    void affichage(Etudiant *V, int n)
         {
             int i=0;
             for(i=0;i<n;i++)
                {
                    printf("%s %d %s\n",V[i].Nom,V[i].NI,V[i].Groupe);
                    printf("\n");
                }
         }
     
     
    void permuter(Etudiant *a, Etudiant *b)
         {
             Etudiant tmp={"",0,""};
             tmp=*a;
             *a=*b;
             *b=tmp;
         }
     
     
    void tri_croissant(Etudiant *V, int n)
         {
             int i=0,j=0,k=1,a=0,b=0;
             for(i=0;i<19;i++)
                {
                    while(k<n)
                         {
                             for(j=0;j<n-k;j++)
                                {
                                    a=V[j].Nom[i];
                                    b=V[j+1].Nom[i];
                                    if(a>b) permuter(&V[j],&V[j+1]);
     
                                }
                            k++;
                         }
                }
         }
     
     
     
    void recherche(char* nom,Etudiant* V,int n)
         {
             int i=0,k=0;
             while(i<n && k!=1)
                {
                    if(strcmp(V[i].Nom,nom)==0)
                      {
                          printf("%s %d %s",V[i].Nom,V[i].NI,V[i].Groupe);
                          k=1;
                      }
                    i++;
                }
                if(k==0) printf("Nom non trouve");
         }
     
    //----------------Fonction principale--------------------------
     
     
    int main()
    {
     
        Etudiant *T=NULL;
        int n=0;
        char nom[20]={0};
     
        printf("saisir le nombre des etudiants... ");
        scanf("%d",&n);
        printf("\n\n");
     
        T=(Etudiant*)malloc(n*sizeof(Etudiant));
        if(T==NULL)
           {
               printf("Echec de l'allocation dynamique!!!");
               exit(0);
           }
        else{
                saisie(T,n);
                tri_croissant(T,n);
                affichage(T,n);
                printf("Nom recherche:");
                scanf("%s",nom);
                recherche(nom,T,n);
                free(T);
            }
     
    	return 0;
    }
    et bien voici ma solution...
    teste avec l'IDE CODE::BLOCKS:
    Process terminated with status 0 (0 minutes, 16 seconds)
    0 errors, 0 warnings

    c gagné, non?

    j'attend vos remarques et vos suggestions:king

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    au hasard et en vrac je n'en citerais que 3.

    Mais c'est quand même pénible de voir que malgré tous les gens qui t'ont aidé tu n'en tiens guère compte.... ah oui suis-je bête. juste pour l'orthographe d'étudiant...

    Bon :

    1) tu as continué à définir ta structure avec un define

    2) tu as continué avec ton algo de tri qui ne trie pas (ou en tous cas vraiment pas de manière optimale n*m*m' opérations

    3) dans ta recherche finale, comme tu n'as pas suivi la discussion ci-dessus, bien que tu aies trouvé le nom, tu continues la boucle.. Pour 10 pas de prblèmes, si tu étais à Paris VI avec 60 000 ou au ministère avec N millions, ben ton temps de réponse tu peux l'attendre...

    je laisse aux autres le soin de continuer.....

    "à quoi ça sert que Ducros y se décarcass ... "
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

Discussions similaires

  1. Réponses: 3
    Dernier message: 26/03/2012, 11h32
  2. Comparaisons et tri des chaines de caractère.
    Par liliemmy dans le forum SQL
    Réponses: 2
    Dernier message: 01/04/2008, 17h52
  3. code de filtre et tri des chaines de caractères
    Par fatenatwork dans le forum Collection et Stream
    Réponses: 18
    Dernier message: 12/03/2008, 16h31
  4. tries des chaine en c++
    Par mouhiballah dans le forum C++
    Réponses: 1
    Dernier message: 14/10/2007, 15h29
  5. Extraire des chaines d'un RES
    Par Dumont dans le forum Langage
    Réponses: 2
    Dernier message: 20/08/2002, 08h13

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