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

SL & STL C++ Discussion :

c++ map et count


Sujet :

SL & STL C++

  1. #1
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut c++ map et count
    Bonjour a tous,

    j'ai une map map<string,int > mymap que j'ai rempli avec les mots d'un fichier et j'aimerai interdire l'enregistrement dans le map des mots qui ne sont pas uniques comme ceci :

    map<string, int>::size_type size
    ;

    map<string,int > mymap;
    {
    while(getline(fichier,line)){
    ...
    size=mymap.count(mot);
    if(count>=1) mymap.erase(mot);
    else mymap.insert(make_pair(mot,position));
    ...
    }//fin while

    }
    toutefois j'ai des problemes pour le premier getline vu que il y'aura pas encore de mot dans le map et donc il enleverra les suivants mots identiques mais pas la premiere ligne ! comment dois-je faire?
    merci d'avance

  2. #2
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    j'ajoutes les mots et sa position dans le map au fure et a mesure du "getline"

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Intuitivement, je ferait plutôt une map<string, vector<int> > où je mettrais toutes les positions, et ensuite, dans une seconde phase, je virerais (éventuellement, car un index ayant plusieurs références n'est pas inutile...) les éléments ayant plusieurs valeurs dans le vecteur.

    Ton code ne peut pas marcher, car si le mot est présent 3 fois, la première fois, il l'ajoute, la seconde, il l'enlève, et la troisième, comme il n'a pas gardé en mémoire que c'est un mot interdit, il l'ajoute à nouveau...
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    Je vais voir comment marche le conteneur vector...
    merci

  5. #5
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    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
    map<string, vector<int> > mots;
    string line;
    int pos=0;
    for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
    
    unsigned beg = 0;//debut mot
    unsigned end = 1;//fin mot
    for(unsigned no_mot=0;end < line.size();++no_mot){
    
    for(;end < line.size() && !is_delim(line[end]);++end);
    
    std::string mot(line,beg,end-beg);
    pos=pos+beg;
    if(mot.size()>=3 ){
    mots.insert(make_pair(mot,pos));
    }
    
    beg = end + 1;
    end = beg + 1;
    }//for..line.size()
    }
    Puis je fais :---->
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /*On enleve les mots "non uniques" */
     
    map<string,vector<int> >::const_iterator
    mots_it (mots.begin()),
    mots_end(mots.end());
     
    for(;mots_it!=mots_end;++mots_it){
    const string & mot_cur = mots_it->first;
    vector<int> & nbelement = mots_it->second;
    if((nbelement.size())>1) mots.erase(mots_it);
    }
    ifs.close();
    mais il y'a un bug :
    invalid initialization of reference of type 'std::vector<int, std::allocator<int> >&' from expression of type 'const std::vector<int, std::allocator<int> >'

    je ne sais pas pourquoi???

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Je n'ai pas le temps de tout relire...

    A priori :

    Pour ajouter des données dans la map, un simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mots[mot].push_back(pos);
    Devrait suffire.

    Pour enlever les éléments dans la map, le fait d'effacer un itérateur l'invalide, et on ne peut plus faire ++ dessus. Il faut donc faire ++ avant d'effacer.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Heu il suffit pas de faire :

    Logiquement, si unMot n'existe pas, il est créé et si il existe, sa valeur associée est mise à jour, ce n'est pas ce que tu veux ?

  8. #8
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    Non je veux enregistrer que les mots uniques dans le map !

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    J'ai l'impression qu'il veut au final faire disparaitre les mots référencés plusieurs fois. Ta solution garderait la dernière référence trouvée dans le cas de références multiples.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Ok.
    Ben t'as plein de solutions. Notamment celle là :

    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
    #include <algorithm>
    #include <set>
    #include <map>
    #include <string>
     
    using namespace std;
     
    char* ListeMots[] = { "Bonjour",
                          "Salut",
                          "Hello",
                          "Hi",
                          "Bonjour",
                          "Coucou",
                          "Hello" };
     
     
    struct Remplir
    {
      Remplir( map<string, int> & tousLesMots,
               set<string>      & doublons )
        : m_map( tousLesMots ),
          m_set( doublons )
      {
      }
     
      template <typename T>
      void operator() ( T const & mot ) const
      {
        // Mot existant
        if ( m_map.find( mot ) != m_map.end() )
          m_set.insert( mot );
        else
          m_map[ mot ] = 'int '; // ou ce que tu veux
      }
     
    private:
      map<string, int> & m_map;
      set<string>      & m_set;
    };
     
     
    struct Supprimer
    {
      Supprimer( map<string, int> & tousLesMots )
        : m_map( tousLesMots )
      {
      }
     
      template <typename T>
      void operator() ( T const & mot ) const
      {
        m_map.erase( mot );
      }
     
    private:
      map<string, int> & m_map;
    };
     
     
    int main()
    {
      map<string, int> motsUniques;
      set<string>      doublons;
     
      // Ajoute tous les mots de la liste dans la map et trouve les doublons
      for_each( ListeMots, ListeMots + sizeof(ListeMots)/sizeof(char**),
                Remplir( motsUniques, doublons ) );
     
      // Supprime de la map les doublons du set
      for_each( doublons.begin(), doublons.end(),
                Supprimer( motsUniques ) );
     
      return 0;
    }

  11. #11
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    merci . Comment je pourrai remplir la liste depuis un fichier passer en argument
    dans la liste avec egalement l'enregistrement de la position du mot par rapport au debut du fichier ?

    int main(int argc, char *argv[])
    {
    char* ListeMots[] = ??



    merci

  12. #12
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    voila tout le code que j'avais entammé

    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
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <map>
    #include <set>
     
    inline bool is_delim(char c){
     return !isalpha(c);
     }
    /***********************main**************************************/
    int main(int argc, char *argv[]){
     
        const char *filename = argv[1];
        const char *filename2 = argv[2];
        std::ifstream ifs(argv[1]);
        std::ifstream if2s(argv[2]);
     
        map<string, vector<int> > mots;
               string line;
               unsigned pos=0; 
     for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
     
                unsigned beg = 0;
                unsigned end = 1;
                for(unsigned no_mot=0;end < line.size();++no_mot){
     
                    for(;end < line.size() && !is_delim(line[end]);++end);
     
                    std::string mot(line,beg,end-beg);//recuperation du mot
                    pos=pos+beg;  
                    if(mot.size()>=3 ){
                    std::cout << "\tajoute le mot[" << mot << "]position = " 
                    << pos  << std::endl;
     
                    mots[mot].insert(pos);
                   }
     
                    beg = end + 1;
                    end = beg + 1;
                }       
            }
     
     
    /*On enleve les doublons*/
     
    map<string,vector<int> >::iterator
                mots_it (mots.begin()),
                mots_end(mots.end());
            for(;mots_it!=mots_end;++mots_it){
                 const std::string & mot_cur = mots_it->first;
                 vector<int> &nbelement = mots_it->second;
                 if((nbelement.size())>1) mots.erase(mots_it);
                }
        ifs.close();
     
        return 0;    
     
    }//main

  13. #13
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par kouack Voir le message
    j'ai une map map<string,int > mymap que j'ai rempli avec les mots d'un fichier et j'aimerai interdire l'enregistrement dans le map des mots qui ne sont pas uniques
    Ta description n'est pas très claire.

    Citation Envoyé par kouack Voir le message
    map<string, int>::size_type size;
    Bof. Mets juste :

    size_t size;

    Citation Envoyé par kouack Voir le message
    map<string,int > mymap;
    {
    while(getline(fichier,line)){
    ...
    size=mymap.count(mot);
    if(count>=1)
    Par définition, une clef est présente au plus une fois dans une map.

    Donc count vaut 0 ou 1.

  14. #14
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    Regarde Si j'utilise un count(mot) :
    en premier count(mot) == 0 mot enregistré
    en second count(mot) ==1 nouveau mot non enregistré
    en troisieme count(mot) == 0 mot enregistré

    Donc ca ne marche qu'1 fois sur 3 (au second)
    Moi je voudrai qu'il l'efface completement

  15. #15
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par kouack Voir le message
    Donc ca ne marche qu'1 fois sur 3 (au second)
    Moi je voudrai qu'il l'efface completement
    Peux-tu faire un effort pour définir clairement ce que "ça" doit faire? Du genre : à la fin, la map doit contenir l'ensemble des ...

    Ce serait plus utile que de poster des tentatives de solutions en C++. Parce que là plusieurs personnes essaient de deviner ce tu veux faire.

  16. #16
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    A priori JolyLoic à mis le doigt sur le résultat attendu.

    J'ai modifié mon premier code pour qu'il aille chercher les mots et les int dans un fichier texte formaté comme cela (j'ai fait une supposition ici, à toi d'adapter selon le fichier que tu as) :

    Citation Envoyé par Fichier test.txt
    Bonjour;256
    Salut;456
    Hello;987
    Hi;123
    Bonjour;654
    Coucou;789
    Hello;789
    et le code donc :

    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
    #include <algorithm>
    #include <sstream>
    #include <set>
    #include <map>
    #include <string>
    #include <fstream>
     
    using namespace std;
     
    // Foncteur qui, à partir d'une ligne, remplit la map et le set
    // Formatage supposé de la ligne : "mot;123"
    struct Remplir
    {
      Remplir( map<string, int> & tousLesMots,
        set<string>      & doublons )
        : m_map( tousLesMots ),
        m_set( doublons )
      {
      }
     
      template <typename T>
        void operator() ( T const & constligne ) const
      {
        string ligne( constligne );
        istringstream iss( ligne );
        string mot;
     
        getline( iss, mot, ';' );
        int i;
        iss >> i;
     
        // Mot existant
        if ( m_map.find( mot ) != m_map.end() )
          m_set.insert( mot );
        else
          m_map[ mot ] = i;
      }
     
    private:
      map<string, int> & m_map;
      set<string>      & m_set;
    };
     
     
    // Foncteur qui supprime un mot d'une map
    struct Supprimer
    {
      Supprimer( map<string, int> & tousLesMots )
        : m_map( tousLesMots )
      {
      }
     
      template <typename T>
        void operator() ( T const & mot ) const
      {
        m_map.erase( mot );
      }
     
    private:
      map<string, int> & m_map;
    };
     
     
    int main()
    {
      ifstream file( "C:\\test.txt" );
     
      map<string, int> motsUniques;
      set<string>      doublons;
     
      // Ajoute tous les mots de la liste dans la map et trouve les doublons
      for_each( istream_iterator<string>(file), istream_iterator<string>(),
        Remplir( motsUniques, doublons ) );
     
      // Supprime de la map les doublons du set
      for_each( doublons.begin(), doublons.end(),
        Supprimer( motsUniques ) );
     
      return 0;
    }
    Après exécution, je n'ai plus que 3 mots dans ma map : "Salut" "Hi" "Coucou" avec les entiers associés.

    Ca répond à ton problème ?

  17. #17
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    Rappel :
    le but est de lire un fichier passer en parametre, d'extraire les mots de plus de caracteres et de les enregistrer avec leur position lorsqu'ils sont des mots uniques

    Pour le moment j'ai :

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <map>
    #include <set>

    inline bool is_delim(char c){
    return !isalpha(c);
    }
    /***********************main*****************************/
    int main(int argc, char *argv[]){

    const char *filename = argv[1];

    //Lecture du fichier
    std::ifstream ifs(argv[1]);

    /*declaration du map avec comme clé le mot lu et comme valeur ses
    *positions dans le fichier
    *exemple : mot=bicyclette pos = 4
    * ...mot=velo pos = 14
    * ...mot=bicyclette pos = 154...*/

    map<string, vector<int> > mots;
    string line;
    unsigned pos=0;
    for(unsigned no_line = 0;std::getline(ifs,line);++no_line){

    unsigned beg = 0;
    unsigned end = 1;
    for(unsigned no_mot=0;end < line.size();++no_mot){

    for(;end < line.size() && !is_delim(line[end]);++end);

    std::string mot(line,beg,end-beg);//recuperation du mot
    pos=pos+beg;
    if(mot.size()>=3 ){
    std::cout << "\tajoute le mot[" << mot << "]position = "
    << pos << std::endl;

    mots[mot].insert(pos);
    }

    beg = end + 1;
    end = beg + 1;
    }
    }

    Puis----->
    /*On enleve les doublons*/
    //je declare un iterateur sur le map pour rechercher les mots avec plusieurs
    //positions dans le fichier

    map<string,vector<int> >::iterator
    mots_it (mots.begin()),
    mots_end(mots.end());
    for(;mots_it!=mots_end;++mots_it){
    const std::string & mot_cur = mots_it->first;
    vector<int> &nbelement = mots_it->second;
    //si le mot a plus d'1 position je l'enleve de la map
    if((nbelement.size())>1) mots.erase(mots_it);

    }//tant qu'on n'a pas atteint la fin du map
    ifs.close();

    return 0;

    }//main

    J'espere que cette fois j'ai été clair?

  18. #18
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par kouack Voir le message
    Rappel :
    le but est de lire un fichier passer en parametre, d'extraire les mots de plus de caracteres et de les enregistrer avec leur position lorsqu'ils sont des mots uniques
    [...]
    J'espere que cette fois j'ai été clair?
    Non.

  19. #19
    Membre averti
    Inscrit en
    Mars 2008
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 53
    Par défaut
    // Supprime de la map les doublons du set
    for_each( doublons.begin(), doublons.end(),
    Supprimer( motsUniques ) );


    j'arrive pas a te suivre et il y'a une erreur :
    `istream_iterator' undeclared (first use this function)

  20. #20
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Revérifie les inclusions, sous Comeau online et Visual C++ 6 ça passe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <algorithm>
    #include <sstream>
    #include <set>
    #include <map>
    #include <string>
    #include <fstream>
    Pour la suppressions des doublons c'est simple : le set contient tous les doublons. On parcoure donc les éléments du set (avec for_each), en appelant pour chaque élément le foncteur Supprimer. On passe la map qui contient tous les mots dans le constructeur du foncteur Supprimer.
    Le foncteur se charge de supprimer de la map chaque élément du set quon lui passe. C'est tout.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Problème dans requête avec count()
    Par BadFox dans le forum Requêtes
    Réponses: 3
    Dernier message: 08/07/2003, 18h02
  2. Problème avec memory mapping
    Par gemai dans le forum C
    Réponses: 13
    Dernier message: 04/07/2003, 09h50
  3. Multiple Count
    Par Antichoc dans le forum Langage SQL
    Réponses: 2
    Dernier message: 31/03/2003, 11h19
  4. Compter le nombre ligne listée (COUNT) ?
    Par StouffR dans le forum Langage SQL
    Réponses: 7
    Dernier message: 02/09/2002, 09h41
  5. Editeur de MAP en delphi pour jeux directX
    Par PetitScorpion dans le forum DirectX
    Réponses: 5
    Dernier message: 09/07/2002, 18h47

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