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 :

Prédicat d'un map


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut Prédicat d'un map
    Bonjour à tous. À l'exercice 7-1 du livre Accelerated C++, on demande de faire évoluer un code servant à compter le nombre d'occurrences de mots, pour que le trie se fasse non plus par ordre alphabétique des mots trouvés (acrobate: 2 fois, jongleur: 3 fois, ...) mais par ordre des occurrences (Mots apparaissant n fois: mes_mots1, Mots apparaissant (n-1) fois: mes_mots2...).

    Quelques lignes au-dessus de la question, l'expression suivante apparait:
    Cela ne peut être un hasard. cmp est le prédicat servant à déterminer l'ordre des éléments. Jusque là, c'est tout ce qui est dit à propos des prédicats des map.

    Voici le code initial:

    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
    #include <iostream>
    #include <map>
    #include <string>
     
    using std::cin;
    using std::cout;
    using std::endl;
    using std::map;
    using std::string;
     
    int main()
    {
    	string s;
    	map<string, int> counters; // store each word and an associated counter
     
    	// read the input, keeping track of each word and how often we see it
    	while (cin >> s)
    		++counters[s];
     
    	// write the words and associated counts
    #ifdef _MSC_VER
    	for (std::map<string, int>::const_iterator it = counters.begin();
    #else
    	for (map<string, int>::const_iterator it = counters.begin();
    #endif
    	     it != counters.end(); ++it) {
    		cout << it->first << "\t" << it->second << endl;
    	}
    	return 0;
    }
    Voici mon 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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include <iostream>
    #include <map>
    #include <string>
     
    using namespace std;
     
    typedef map<string, int> Map;
    typedef Map::const_iterator Map_iter;
     
    bool cmp(const Map_iter& a, const Map_iter& b) {
    	return a->second < b->second;
    }
     
    int main()
    {
    	string s;
    	Map counters(cmp);
     
    	while (cin >> s)
    		++counters[s];
     
    	for (Map_iter it = counters.begin(); it != counters.end(); ++it)
    		/* code à ajouter pour afficher les occurrences,
                    suivis des mots correspondants */
    	return 0;
    }
    La compilation échoue (ligne Map counters(cmp)). Au début j'avais écrit cmp() de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool cmp(const pair<string, int>& a, const pair<string, int>& b) {
    	return a->second < b->second;
    }
    ... sans davantage de succès.

  2. #2
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Hum non, ton prédicat doit prendre en argument le type des clefs de ta map. Voici comment j'écrirais ç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
    18
    19
    20
    21
    22
    23
     
    #include <iostream>
    #include <map>
    #include <string>
     
    struct myPred
    {
        bool operator()(const std::string& a, const std::string& b) const
        {
            return a<b;
        }
    };
     
    int main()
    {
    	std::string s;
    	std::map<std::string, int, myPred> counters;
     
    	while (std::cin >> s)
    		++counters[s];
     
    	return 0;
    }

    je passe toujours mon prédicat comme template il y'a surement une différence avec le fait de le passer à la construction mais je connais pas.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  3. #3
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    J'avais eu les mêmes idées que goran_kajfes et suis tout aussi perplexe...
    Il me semble que la technique utilisée par Goten, pour pertinente qu'elle puisse être par ailleurs, ne fait pas partie des 'acquis' au point où l'exercice est donné dans le livre de Koenig et Moo.
    D'autre part, ce qu'il faudrait comparer dans cet exercice, ce sont les valeurs et non les clés...
    Or si je comprends bien, dans
    (donné peu avant par KM)
    le prédicat cmp sert uniquement à comparer les clés, non ?
    Je me demande s'il ne faudrait pas créer une map qui fasse de chaque valeur de la map actuelle une clé qui aurait pour valeur un vecteur contenant tous les mots ayant cette valeur dans la clé actuelle...

  4. #4
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par goran kajfes Voir le message
    Bonjour à tous. À l'exercice 7-1 du livre Accelerated C++, on demande de faire évoluer un code servant à compter le nombre d'occurrences de mots, pour que le trie se fasse non plus par ordre alphabétique des mots trouvés (acrobate: 2 fois, jongleur: 3 fois, ...) mais par ordre des occurrences (Mots apparaissant n fois: mes_mots1, Mots apparaissant (n-1) fois: mes_mots2...).
    Je pense que là est le problème, tu as mal compris l'énoncé (le gras est de moi) :
    Expand the program from §1.2/124 to produce its output sorted by occurence count.
    Il ne faut pas changer la façon dont le tri est fait dans la map, car la façon dont il est fait est nécessaire au bon fonctionnement du programme. Il faut juste changer l'affichage pour que ce dernier se fasse dans un autre ordre.

    C'est justement un bon exercice pour voir si on a bien compris les map, et le fait que l'ordre défini sur les clefs sert avant tout à différencier une clef d'une autre. C'est l'un des premiers exercices que je donne à mes élèves.

    J'ai bien vérifié, tu as tout en main à la fin du chapitre 7 pour résoudre ce problème. Je te laisse un peu chercher ?
    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.

  5. #5
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Le code suivant fonctionne sur mon système. Il crée une seconde map où la clé est un nombre de lignes n et la valeur est un vecteur contenant les mots attestés dans n lignes.

    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
    #include <iostream>
    #include <map>
    #include <string>
    #include <vector>
     
    using namespace std;
     
    int main()	
    {
     string s;
     map<string, int> counters; // store each word and an associated counter
     
     // read the input, keeping track of each word and how often we see it
     while (cin >> s)
          ++counters[s];
     
    // on crée une nouvelle map
    // formée de paires dont la clé représente un nombre de lignes
    // et dont la valeur est un vecteur de strings 
    // contenant tous les mots apparaissant dans le nombre de lignes
    // représenté par la clé
     map<int, vector<string> > newcounters;
     
     for (map<string, int>::const_iterator it = counters.begin();it != counters.end(); ++it)
    	newcounters[it->second].push_back(it->first);
     
    // on imprime le contenu de cette nouvelle map
     for(map<int, vector<string> >::const_iterator it = newcounters.begin();
    	  it != newcounters.end(); ++it) {
     	      cout << "\nMots présents dans " << it->first << " lignes : " << endl << endl;
    	      for(vector<string>::const_iterator it2 = it->second.begin(); it2 != it->second.end();++it2)
    		cout <<  *it2 << ' '; 
     }on 
      return 0;
    }
    Le code est assez compact mais présente l'inconvénient de créer DEUX map simultanément. Une solution qui se contenterait de la première map et qui l'imprimerait correctement occuperait sans doute moins de mémoire.

  6. #6
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Et ce code fonctionne aussi, sans créer une deuxième map :

    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
    #include <iostream>
    #include <map>
    #include <string>
    #include <algorithm>
     
    using namespace std;
     
    int main()	
    {
      string s;
      map<string, int> counters; // store each word and an associated counter
     
      // read the input, keeping track of each word and how often we see it
      while (cin >> s)
        ++counters[s];
     
      int max_freq = 0;
    // trouver la plus grande valeur de counter (correspondant au  mot le plus fréquent) 
      for(map<string, int>::const_iterator it = counters.begin(); it != counters.end(); ++it)  
        max_freq = max(max_freq, it->second);    
     
      for (int i = 1;  i<= max_freq;++i) { // on recherche les mots présents dans i lignes
        cout << endl << endl;
        cout << "Mots figurant dans : " << i << " lignes :" << endl;
     
        for (map<string, int>::iterator it = counters.begin(); it != counters.end(); ++it) {
          if (it->second == i) {
    	cout << it->first << ' ';
          } 
        }
      }
      return 0;
    }

  7. #7
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    La deuxième solution me semble assez horrible en terme de complexité algorithmique.

    Personnellement, ce qui me vient le plus directement en tête est une solution où l'on copie le contenu de la map dans un vector<pair<string, int> > (puisque l'ordre dans un vector est contrôlé par l'utilisateur), puis où l'on trie ce vector selon le critère requis.
    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.

  8. #8
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    La deuxième solution me semble assez horrible en terme de complexité algorithmique.
    C'était bien mon impression aussi...

    Citation Envoyé par JolyLoic Voir le message
    Personnellement, ce qui me vient le plus directement en tête est une solution où l'on copie le contenu de la map dans un vector<pair<string, int> > (puisque l'ordre dans un vector est contrôlé par l'utilisateur), puis où l'on trie ce vector selon le critère requis.
    Est-ce que ce serait 'mieux' que la première solution finalement (qui recopie une map dans une autre map) ?
    L'idéal serait sans doute d'éviter une recopie de conteneur, vecteur ou map, et de trouver un algo un peu plus élégant que la 'seconde solution' pour afficher directement le contenu de la map 'counters' ?

  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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    'mieux' selon quels critères ?

    En terme de simplicité de code, ça doit se valoir à peu près.

    En terme de performance, il y a des chances que ce soit mieux avec un vector, mais on reste au même niveau de complexité algorithmique (et en terme de perfs, on gagnerait sûrement plus encore avec un vector<map<string, int>::const_iterator>).

    Ça dépend à mon avis en grande partie dans un vrai programme de ce que l'on désirerait faire après avec ces données. Si on désire manipuler : "l'ensemble des mots présents 3 fois", ta solution est probablement plus intéressante.
    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 régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    Merci pour vos réponses.

    Goten: on n'est pas encore censé savoir qu'une structure peut « abriter » des fonctions, ni que des maps peuvent avoir 3 arguments.

    Citation Envoyé par JolyLoic Voir le message
    Je pense que là est le problème, tu as mal compris l'énoncé (le gras est de moi)
    Un énoncé est comme le code pénal: tout ce qui n'est pas interdit est autorisé. On ne me dit pas de ne pas changer la déclaration du map, mais de modifier la sortie. En modifiant le map (sa déclaration), je modifie ainsi sa sortie. Mais je ne suis pas dans la tête de Koenig et Moo.

    Voilà comme les auteurs définissent le map<K, V> m(cmp); :
    map<K, V> m(cmp);
    Creates a new empty map with keys of type const K and values of type V, that uses the predicate cmp to determine the order of the elements.
    Ça ressemble quand même beaucoup à ce qui m'est demandé. Par contre, j'ai eu beau chercher un moment sur internet, je n'ai rien trouvé qui corresponde à ce genre de déclaration. Est-ce que quelqu'un saurait l'utiliser?

    Je ne sais pas ce que tu en penses mais je trouve beaucoup d'exercices du livre ambigüs (et ce n'est pas parce que c'est de l'anglais). J'espère que leur sujets d'examens le sont moins. Par contre, j'apprécie tout le reste (le générateur de phrases aléatoires m'a bluffé).

    ptyxs: J'ai aussi créé une deuxième map. Je n'avais pas regardé ton code avant, mais le reste de tes messages (qui parlait notamment de 2 maps simultanées). Je ne le donne pas. C'est quasiment un copier-coller du tien: 3 boucles for, map<int, vector<string> > ...
    Avec ta deuxième méthode, tu répertories des fréquences sans qu'elles ne soient associées au moindre mot.

    Je vais attendre un peu avant de mettre en résolu.

  11. #11
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par goran kajfes Voir le message
    Un énoncé est comme le code pénal: tout ce qui n'est pas interdit est autorisé. On ne me dit pas de ne pas changer la déclaration du map, mais de modifier la sortie. En modifiant le map (sa déclaration), je modifie ainsi sa sortie. Mais je ne suis pas dans la tête de Koenig et Moo.
    Tout à fait, c'est autorisé. Le problème, c'est que ça ne te mènera pas vers la solution. Le comparateur associé à une map sert à comparer entre elles les valeurs des clefs, et rien d'autre. Tu ne pourras pas t'en servir pour comparer les nombres d'occurrence. En outre, ce comparateur doit être stable, c'est à dire que si un jour, il dit A<B, le lendemain, il doit toujours dire A<B. Tu voudrais un comparateur qui tiendrait compte du nombre d'occurrence alors que celui-ci varie au cours du temps.
    Citation Envoyé par goran kajfes Voir le message

    Voilà comme les auteurs définissent le map<K, V> m(cmp); :

    Ça ressemble quand même beaucoup à ce qui m'est demandé.
    Peut-être, mais dans ce cas, la ressemblance est trompeuse.
    Citation Envoyé par goran kajfes Voir le message
    Par contre, j'ai eu beau chercher un moment sur internet, je n'ai rien trouvé qui corresponde à ce genre de déclaration. Est-ce que quelqu'un saurait l'utiliser?
    Il s'agit d'un raccourci/un bug des auteurs. Le comparateur se défini comme indiqué par Goten par un argument template supplémentaire. Ce constructeur sert alors pour passer une instance particulière de ce template. 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <map>
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    class Cmp
    {
    public:
    	Cmp(bool reverse) : myReverse(reverse) {}
    	bool operator()(string const &s1, string const &s2) const
    	{
    		if (myReverse)
    			return s2<s1;
    		else
    			return s1<s2;
    	}
    private:
    	bool myReverse;
    };
     
    void f(bool b)
    {
    	Cmp myCmp(b);
    	map<string, string, Cmp> dico(myCmp);
    	dico["chat"] = "cat";
    	dico["souris"] = "mice";
     
    	for(std::map<string, string, Cmp>::const_iterator it = dico.begin();
    		it != dico.end();
    		++it)
    	{
    		cout << it->first << "=>" << it->second << endl;
    	}
    }
     
    int main()
    {
    	f(true);
    	f(false);
    }
    Citation Envoyé par goran kajfes Voir le message
    Je ne sais pas ce que tu en penses mais je trouve beaucoup d'exercices du livre ambigüs (et ce n'est pas parce que c'est de l'anglais).
    Je n'ai pas regardé en détail, vu que quand j'ai eu ce livre entre les mains, je n'étais plus vraiment leur public cible, mais ça ne me choquerait pas trop. Un vrai programme dans la vraie vie sera toujours mal défini, et aura plusieurs façon d'être obtenu. Je trouve donc des sujets un peu ouverts plus stimulants qu'autre chose.
    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.

  12. #12
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Ouai les exercices sont un peu vagues. (je dirais pas forcément ambiguë) mais comme loicjoly je pense que c'est un plus et que c'est voulu.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    Salut.

    Citation Envoyé par JolyLoic Voir le message
    Tout à fait, c'est autorisé. Le problème, c'est que ça ne te mènera pas vers la solution. Le comparateur associé à une map sert à comparer entre elles les valeurs des clefs, et rien d'autre.
    Voilà pourquoi ça ne marchait pas. Donc le prédicat prend obligatoirement en argument une variable de même type que celle de la clé du map. Je m'acharnais à lui refiler un map ou un pair...

    Citation Envoyé par JolyLoic Voir le message
    Il s'agit d'un raccourci/un bug des auteurs. Le comparateur se défini comme indiqué par Goten par un argument template supplémentaire.
    C'est bon à savoir.

    Citation Envoyé par Goten Voir le message
    Ouai les exercices sont un peu vagues. (je dirais pas forcément ambiguë)
    Vague, oui. Et il est très fréquent que les fichiers de données (dossier data/) ne permettent pas de tester en détail les exécutables (pour ne prendre qu'un exemple: un programme est censé cherché les url d'un fichier texte, et le seul *.html présent dans data/ ne contient pas d'url...).

    Un grand merci à vous. Je passe en résolu.

  14. #14
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    Citation Envoyé par goran kajfes Voir le message
    ptyxs: J'ai aussi créé une deuxième map. Je n'avais pas regardé ton code avant, mais le reste de tes messages (qui parlait notamment de 2 maps simultanées). Je ne le donne pas. C'est quasiment un copier-coller du tien: 3 boucles for, map<int, vector<string> > ...
    Avec ta deuxième méthode, tu répertories des fréquences sans qu'elles ne soient associées au moindre mot.
    En ce qui concerne la deuxième méthode, tu as raison, le fait d'imprimer les fréquences qui ne correspondent à aucun mot n'est sans doute pas très souhaitable. On peut tout de même remédier à cela assez facilement, la version suivante évite cette maladresse et donne une sortie un peu différente mais qui me semble envisageable (il reste que, comme le signalait JolyLoic, l'algorithmique de cette deuxième méthode n'est par ailleurs pas très satisfaisante (dans la mesure où elle parcourt toute la map pour chaque nombre de lignes)) :

    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
    #include <iostream>
    #include <map>
    #include <string>
    #include <algorithm>
     
    using namespace std;
     
    int main()	
    {
      string s;
      map<string, int> counters; // store each word and an associated counter
     
      // read the input, keeping track of each word and how often we see it
      while (cin >> s)
        ++counters[s];
     
      int max_freq = 0;
      // trouver la plus grande valeur de counter (correspondant au  mot le plus fréquent) 
      for(map<string, int>::const_iterator it = counters.begin(); it != counters.end(); ++it)  
        max_freq = max(max_freq, it->second);    
     
      for (int i = 1;  i<= max_freq;++i) { // on recherche les mots présents dans i lignes
        for (map<string, int>::iterator it = counters.begin(); it != counters.end(); ++it) {
          if (it->second == i) {
    	cout << "Mot figurant dans : " << i << " lignes : ";
    	cout << it->first << endl;
          } 
        }
      }
      return 0;
    }

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    @ptyxs: c'est noté.

    Tant que tu es là, tu es peut-être en mesure de m'aider pour autre chose. Je ne crois pas que créer un autre sujet soit judicieux. J'aurais pu t'envoyer un message privé.

    Voilà mon problème. J'en bave pour résoudre certains exos, à cause des fichiers d'en-têtes, des makefile, de la façon d'intégrer un template à un programme... Ce sont des choses qui ne sont quasiment jamais expliquées dans le livre.

    Au chapitre 5, je m'étais cassé les dents sur le makefile. À l'exercice 5-2, j'en étais arrivé à copier les fonctions de 5 ou 6 fichiers fournis par les auteurs dans un gros main car j'étais incapable de créer un petit fichier *.cc et de le raccorder aux autres. Après avoir perdu pas mal de temps, j'ai lu ce tutoriel. Même s'il n'est pas exhaustif, il m'a quand même permis de juste coder ce qui était nécessaire et de modifier les makefiles des auteurs en conséquence (donc ça été bon au niveau des makefiles et des compilations pour le chapitre 5, 6 et 7).

    Arrive le chapitre 8, et là je me recasse les dents sur les fichiers d'en-têtes à cause des templates. Les auteurs n'expliquent même pas pourquoi ceux-ci sont placés dans des *.h. Pour résoudre l'exo 8-1, j'ai dû créé un répertoire où j'ai copié 8 fichiers précédemment vus pour y ajouter mon propre analysis.h. Je suis incapable de juste créer analysis.h et de modifier le makefile des auteurs pour que la compilation s'opère. À l'exercice 8-3, je crée une fonction template <class It> double median(It begin, It end), elle marche, mais pas si je "templétise" aussi le double (même si double est donné à une variable lors de l'appel). Et je serais incapable d'intégrer cette fonction à grade.h, Student_infos.h... sans les copier à part dans un répertoire. De toute façon, même en les copiant à part, ça ne marche pas.

    À l'exo 9, je n'arrive pas à faire lier le nouveau xref à split.h. Je donne l'en-tête split.h à xref-nv.cc mais ce dernier ne reconnait pas la fonction split(). Même en copiant le contenu de split.h (qui contient le template) dans xref-nv.cc, ça ne fonctionne pas: split() n'est toujours pas trouvé.

    Je suis dépassé. (decelerated c++) Ça se soigne?

    @ptyxs: comment avais-tu fait à l'époque? Connaissant déjà le C, les makefile n'avaient plus de secrets pour toi? Mais il me semble que les templates sont spécifiques à C++. Pourquoi je bloque quand j'essaie de compiler des programmes composés de plusieurs fichiers avec des templates?

  16. #16
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    http://cpp.developpez.com/faq/cpp/?p...VERS_templates contient peut-être des éléments de réponse (même s'il n'est plus totalement à jour).
    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.

  17. #17
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par goran kajfes Voir le message
    @ptyxs: c'est noté.

    Tant que tu es là, tu es peut-être en mesure de m'aider pour autre chose. Je ne crois pas que créer un autre sujet soit judicieux. J'aurais pu t'envoyer un message privé.

    Voilà mon problème. J'en bave pour résoudre certains exos, à cause des fichiers d'en-têtes, des makefile, de la façon d'intégrer un template à un programme... Ce sont des choses qui ne sont quasiment jamais expliquées dans le livre.

    Au chapitre 5, je m'étais cassé les dents sur le makefile. À l'exercice 5-2, j'en étais arrivé à copier les fonctions de 5 ou 6 fichiers fournis par les auteurs dans un gros main car j'étais incapable de créer un petit fichier *.cc et de le raccorder aux autres. Après avoir perdu pas mal de temps, j'ai lu ce tutoriel. Même s'il n'est pas exhaustif, il m'a quand même permis de juste coder ce qui était nécessaire et de modifier les makefiles des auteurs en conséquence (donc ça été bon au niveau des makefiles et des compilations pour le chapitre 5, 6 et 7).

    Arrive le chapitre 8, et là je me recasse les dents sur les fichiers d'en-têtes à cause des templates. Les auteurs n'expliquent même pas pourquoi ceux-ci sont placés dans des *.h. Pour résoudre l'exo 8-1, j'ai dû créé un répertoire où j'ai copié 8 fichiers précédemment vus pour y ajouter mon propre analysis.h. Je suis incapable de juste créer analysis.h et de modifier le makefile des auteurs pour que la compilation s'opère. À l'exercice 8-3, je crée une fonction template <class It> double median(It begin, It end), elle marche, mais pas si je "templétise" aussi le double (même si double est donné à une variable lors de l'appel). Et je serais incapable d'intégrer cette fonction à grade.h, Student_infos.h... sans les copier à part dans un répertoire. De toute façon, même en les copiant à part, ça ne marche pas.

    À l'exo 9, je n'arrive pas à faire lier le nouveau xref à split.h. Je donne l'en-tête split.h à xref-nv.cc mais ce dernier ne reconnait pas la fonction split(). Même en copiant le contenu de split.h (qui contient le template) dans xref-nv.cc, ça ne fonctionne pas: split() n'est toujours pas trouvé.

    Je suis dépassé. (decelerated c++) Ça se soigne?

    @ptyxs: comment avais-tu fait à l'époque? Connaissant déjà le C, les makefile n'avaient plus de secrets pour toi? Mais il me semble que les templates sont spécifiques à C++. Pourquoi je bloque quand j'essaie de compiler des programmes composés de plusieurs fichiers avec des templates?
    Au pire si c'est juste pour faire des tests, installe un EDI, comme ça tu te prendras pas la tête à faire des make.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    Salut!

    J'ai créé 2 nouveaux sujets ici et ici.

    J'ai pu faire l'exo 8-1 uniquement en ajoutant un *.h et en modifiant le makefile, mais ça reste compliqué.

  19. #19
    Membre averti
    Profil pro
    professeur des universités à la retraite
    Inscrit en
    Août 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : professeur des universités à la retraite

    Informations forums :
    Inscription : Août 2008
    Messages : 364
    Points : 439
    Points
    439
    Par défaut
    @goran kajfes eh bien pour tout t'avouer, j'ai peu fait d'exercices du livre de Koenig et Moo (mais attention : je ne suis pas un gros paresseux, hein, car j'ai fait pas mal d'exercices de l'excellent bouquin récent de Stroustrup Programming : Principles and Practise Using C++ qui par parenthèses comporte un certain nombre d'exercices corrigés sur le site du livre).
    Il est parfaitement exact cependant que le manque de la moindre indication sur les problèmes concrets de compilation est assez criant dans ce bouquin, le Koenig-Moo, (par ailleurs tout à fait passionnant).
    Pour ma part, je suis sous Linux et j'utilise g++ (et l'éditeur de texte Kate) qu'en est-il pour toi ?
    J'essaierai de regarder les problèmes que tu soulèves dans les fils que tu as créé.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 128
    Points : 122
    Points
    122
    Par défaut
    J'ai résolu tous les exos du chapitre 8 à l'exception du 8-2 (où je n'ai fait que la moitié de ce qui est demandé; la moitié que j'ai faite est sans doute fausse à 75%, mais bon, c'est exo est assez ingrat et ce n'est pas grave).

    Causes de mes galères d'hier:
    exo1: compilation pas évidente à mette en place (un même *.cc pouvant donner deux *.o, des *.cc à aller chercher dans pleins de répertoires différents...)
    exo2: ultra-ingrat, même s'il aide à comprendre le fonctionnement de certaines fonctions
    exo3: il me manquait certaines informations. Quelques pièges à éviter pour le test sur un grand nombre de données...
    exo5: j'ai un peu triché en virant le 2ème paramètre de la fonction xref. L'astuce donnée par 3DArchi pour l'exo 3 m'a été indispensable.

    Pour les autres, j'ai eu un peu moins de difficultés.

    Au final, le côté trop accéléré du livre (il fait trop d'impasses sur les templates appliqués au retours de fonction, et sur la compilation) m'a pénalisé... ainsi qu'un trop grand nombres d'heures passées devant l'ordinateur, il faut bien le dire.

    J'espère que je ne me recasserais pas les dents une 3ème fois dans 3 chapitres...

    @ptyxs: merci pour l'info sur les exos de Stroustrup (et pour l'info sur la sortie de son nouveau livre).
    Pour ma part, j'utilise... g++ et kate. Je n'ai jamais touché un IDE (contrairement à Goten). Je n'en ai jamais vu non plus en action. C'est presque un autre monde.
    Est-ce que tu arrives à changer l'indentation d'un texte sans utiliser Ctrl+i? Je ne peux plus utiliser la touche Tab à cette fin sous Kate (3.3.2) et je ne peux pas non plus changer le raccourci-clavier correspondant (auxiliaire).

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

Discussions similaires

  1. prédicat pour min_element d'une std::map
    Par Kurisu dans le forum SL & STL
    Réponses: 6
    Dernier message: 11/09/2006, 19h27
  2. [EJB2.1 Entity] [BES] Mapping automatique et clés étrangères
    Par Bobby McGee dans le forum Java EE
    Réponses: 3
    Dernier message: 15/10/2003, 10h33
  3. Réponses: 2
    Dernier message: 11/07/2003, 18h24
  4. Problème avec memory mapping
    Par gemai dans le forum C
    Réponses: 13
    Dernier message: 04/07/2003, 09h50
  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