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 :

Algorithmie: manipulation de fichier et strings c++


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 18
    Par défaut Algorithmie: manipulation de fichier et strings c++
    Bonsoir,

    je m'amuse à apprendre le c++ et j'ai trouvé un problème que je cherche à résoudre:

    On a un fichier contenant des noms, et à côté de ces noms des cours que ces noms suivent.
    Jean: MATHS, SCIENCE, SPORT
    Mathieu: MATHS, SPORT
    Ivan: MATHS, SCIENCE

    Et le but de l'exercice est d'avoir un fichier de sortie sous la forme suivante:
    MATHS: Jean, Mathieu, Ivan
    SCIENCE: Jean, Ivan
    SPORT: Jean, Mathieu

    Je commence d'abord par lire le fichier ligne par ligne (dans un tableau de string avec un string pour chaque ligne).
    Ensuite je traite chaque ligne pour en extraire le nom (partie avant le ':') et les cours qu'il doit suivre. Le tout dans une structure ELEVE(string nom, vector<string> cours, int nbcours).


    Ensuite je créé un tableau contenant tous les ELEVEs et j'extrait les cours que je mets dans un vecteur de string (en supprimant les doubles).
    Et enfin je recréé une structure similaire au type ELEVE, sauf que le nom est désormais celui du cours, et le vector<string> contient les élèves.

    Mais je trouve que cette approche est lourde et longue. Qu'en pensez vous?

  2. #2
    Membre Expert
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    872
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 872
    Par défaut
    A ta place j'utiliserais plutot une map de vector de string :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    map<string, vector<string> >
    En cle je mettrais le nom de l'eleve puis toutes les matieres qu'il a dans le vector de string. Ensuite le filtre serait plus simple a faire. Cependant ca t'oblige a le faire en 2 fois de cette facon (on enregistre puis on recree une map), tu peux tres bien faire directement ceci (un code sera plus clair qu'une explication) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my_map["MATHS"].push_back("olivier");
    Donc stocker directement les eleves dans la matiere. Je ne pense pas qu'on puisse faire mieux...

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    On peut aussi utiliser dans le même esprit std::multimap.

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    une autre approche est d'avoir un type Matiere :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct Matiere {
       std::string nom;
       std::set<Eleve*> eleves; // peut être un ref wrapper à la place d'un pointeur
       // ...
    };
    Et la classe Eleve devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct Eleve {
       std::string nom;
       std::set<Matiere*> matieres; // peut être un ref wrapper aussi
       int nbMatieres() const { return matieres.size(); }
       // ...
    };
    Il faut ensuite stocker les Eleves et les Matieres quelque part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct Ecole {
       std::set<Matiere> matieres;
       std::set<Eleve> eleves;
       // ...
    };
    Cette une approche plus solide mais plus lourde à mettre en place.

    Une fois que les données sont rentrées, obtenir

    Jean: MATHS, SCIENCE, SPORT
    Mathieu: MATHS, SPORT
    Ivan: MATHS, SCIENCE

    ou
    MATHS: Jean, Mathieu, Ivan
    SCIENCE: Jean, Ivan
    SPORT: Jean, Mathieu

    n'est qu'une question d'ordre de parcours des données.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 18
    Par défaut
    Salut!

    Merci beaucoup pour vos réponses, c'est tellement plus simple de cette manière plutôt qu'avec mes anciennes structures.

    J'ai opté pour la solution la plus simple: créér directement une seule map:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    map<string, set<string> > mymap;
    mymap["MATHS"].push_back("olivier");
    J'ai du mal à comprendre comment accéder aux données de map sans itérateur pour pouvoir ensuite afficher le string et son set associé et enfin parcourir son set avec les itérators.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Salut !

    std::set
    n'a pas de membre appelé push_back, ce serait plutôt insert.

    Si tu utilises C++11, tu peux parcourir tes objets comme dans cet exemple:

    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
    #include <iostream>
    #include <map>
    #include <string>
    #include <set>
    #include <utility>
     
    int main(void) {
      using std::map;
      using std::set;
      using std::string;
      using std::pair;
     
      map<string, set<string>> my_map = {{"MATHS", {"Jean","Mathieu","Ivan"}}, {"SCIENCE", {"Jean","Ivan"}}, {"SPORT", {"Jean","Mathieu"}}};
      for(pair<string const&, set<string> const&> matiere : my_map) {
        std::cout << matiere.first << ": ";
        for(string const& eleve : matiere.second) {
          std::cout << eleve << " ";
        }
        std::cout << std::endl;
      }
     
      return 0;
    }
    Mais rien ne t'empêche d'utiliser un intérateur. Le seul truc qui change avec les itérateurs de map, c'est que le déréférencer pointe vers une paire dont le premier élément est la clé (la matière) et le second la valeur (le set d'élèves). On ne peut pas avoir d'itérateur sur les valeurs seules.

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2014
    Messages : 18
    Par défaut
    Merci
    Ensuite l'écriture se fait naturellement à la sortie

    Les élèves semblent s'afficher par ordre alphabétique mais cela dépend pour les cours. Pour l'instant je reprend les lignes du fichiers de sortie et je les reclasse ensuite par ordre alphabétique en les mettant dans un vecteur (tri à bulle ).Y a t il un moyen plus simple?

    Je pense que je vais faire ça avec des itérateurs, dans l'ennoncé du problème je ne trouve pas de #include <pair>. Ou sinon il serait plus simple d'utiliser des map<string,vector<string>> ?

  8. #8
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      map<string, set<string>> my_map = {{"MATHS", {"Jean","Mathieu","Ivan"}}, {"SCIENCE", {"Jean","Ivan"}}, {"SPORT", {"Jean","Mathieu"}}};
      for(pair<string const&, set<string> const&> matiere : my_map) {
    Ce ne serait pas plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(pair<string const&, set<string> > const& matiere : my_map)
    voire carrément :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(auto const& matiere : my_map)

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

Discussions similaires

  1. Manipulation de fichier (copier, supprimer, déplacer)
    Par Guigui_ dans le forum Général Python
    Réponses: 1
    Dernier message: 21/10/2004, 10h26
  2. Manipulation des fichiers
    Par monsau dans le forum Langage
    Réponses: 7
    Dernier message: 21/09/2004, 17h45
  3. [LG]Manipulation de fichiers
    Par yffick dans le forum Langage
    Réponses: 29
    Dernier message: 10/01/2004, 15h04
  4. Manipulation de fichiers - gestion d'extensions
    Par ulukai dans le forum Linux
    Réponses: 13
    Dernier message: 02/07/2003, 15h28
  5. Réponses: 2
    Dernier message: 18/01/2003, 17h06

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