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

Langage C++ Discussion :

somme des élements d'une map et d'un vecteur.


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 61
    Par défaut somme des élements d'une map et d'un vecteur.
    Bonjour,

    J'ai un liste d'élément dans une maps et dans un vecteur.
    Je veux faire la somme des éléments mais ça me renvoie des eereurs à la compilation.

    Quelqu'un saurait il pourquoi?

    Merci d'avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    map<string, map<string, int> > c_sizes;
     
    for (map<string, map<string, int> >::iterator marqueur = c_sizes.begin(); marqueur != c_sizes.end(); marqueur++){
    Sc_sizes-> c_sizes.second;
    }
    ***************************************************************************************************
    map<string, vector<int> > t_marqueurs;
    for(vector<int>::iterator m = t_marqueurs["h.."].begin(); m != t_marqueurs["h.."].end(); ++m)
        fichier2 << *m << " \t";
    int SM= accumulate (t_marqueurs.begin(), t_marqueurs.end(), 0);

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,

    Je comprends que le compilateur soit perplexe
    Tu n'as pas bien l'air de voir ce que fait accumulate. Mis sous forme plus familière c'est équivalent à une bête boucle for :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int std::accumulate(map<string, vector<int> >::iterator first, 
                        map<string, vector<int> >::iterator last, 
                        int val)
    {
       for (; first!= last; ++first)
          val = val + *first;
       return val;
    }
    Tu essayes donc d'additionner des entiers avec des std::pair<std::string, std::vector<int>> (qui est le type de*first)...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 61
    Par défaut
    Re bonjour,
    Merci pour la réponse mais le compilateur n'est pas content quand j'applique ce que tu m'as dit. Il me renvoie une erreur no match for 'operator+'.
    J'ai remplacé les "val" par les noms des maps.

    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
     
     
    map<string, vector<int> > tailles_marqueurs;
    int accumulate(map<string, vector<int> >::iterator first,
                        map<string, vector<int> >::iterator last,
                        int t_marqueurs)
        {
        for (tailles_marqueurs; first!= last; ++first)
          t_marqueurs = t_marqueurs + *first;
        return t_marqueurs;
        }
     
    map<string, map<string, int> > c_sizes;
    int accumulate(map<string, map<string, int> > ::iterator first,
                        map<string, vector<int> >::iterator last,
                        int c_sizes)
        {
        for (c_sizes; first!= last; ++first)
          c_sizes = c_sizes + *first;
        return c_sizes;
        }

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 61
    Par défaut
    Finalement j'ai placé la fonction en dehors du main, et je l'ai appelé. Mais ça marche toujours pas.
    Je me demande pourquoi.
    Merci d'avance

    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
     
     
    int std::accumulate(map<string, vector<int> >::iterator first,
                        map<string, vector<int> >::iterator last,
                        int val)
    {
       for (; first!= last; ++first)
          val = val + *first;
       return val;
    }
     
    int main() {
    accumulate( map<string, vector<int> > tailles_marqueurs::iterator first,
                            map<string, vector<int> >::iterator last,
                            int SommeTilleMarqueur);
     
        accumulate(map<string, vector<int> > chromosome_sizes::iterator first,
                            map<string, vector<int> >::iterator last,
                            int SommeTailleChromosome);
     
    }

  5. #5
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Ce que faisait Azrar, ce n'est pas te proposer du code qui marche, c'est t'expliquer ce que faisait std::acummulate(). Recompier son code ne va pas marcher, parce qu'il ne peut pas marcher.

    Reflechi au concept : sur une map, qu'est-ce que ça signifie d'ajouter les éléments entre eux ? Ajouter les valeurs ? Ajouter les clefs ? Ajouter les deux ensemble ? La librairie standard ne va pas prendre cette décision à ta place.

    Par contre, elle fournit les outils pour que tu puisses faire ce que tu veux. Regarde cette référence. Il existe deuc versions de std::accumulate() - la première est celle que tu utilises et qui ne fonctionne pas pour ce que tu veux faire. La seconde est plus interessante : elle prends un paramètre additionnel, qui est un prédicat binaire dont la forme est (pour un type de donnée T et un type résultat R) :

    R predicat(R resultat_precedent, T nouvelle_valeur).

    Reste à fécrire ce prédicat. Ca peut être un pointeur sur fonction, mais il est plus intéressant d'utiliser un foncteur (une classe avec un opérateur() public).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template <class R, class A1, class A2>
    struct map_value_adder
    {
      R operator()(R prev, const std::pair<A1,A2>& value)
      {
        return prev + value.second;
      }
    };
    Le problème ici est que A2 est (pour toi) std::vector<int>. Hors, on ne peux pas additionner des vecteurs (ça n'a pas vraiment de sens : quelle opération effectuer ?). En partant du principe que l'idée est de faire la somme de toutes les valeurs dans chaque vecteur, on peut écrire une spécialisation partielle du foncteur. Ca se complique un peu :

    (edit : correction d'erreurs de compilation ; cf. mon post suivant).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class A1, class A2>
    struct map_value_adder<typename std::vector<A2>::value_type, A1, std::vector<A2> >
    {
    	typedef typename std::vector<A2>::value_type result_type;
    
    	result_type operator()(result_type prev, const std::pair<A1, A2 std::vector<A2> >& value)
    	{
    		const std::vector<A2> & v = value.second;
    		return std::accumulate(v.begin(), v.end(), prev);
    	}
    };
    Du coup, pour utiliser ce code, il faut écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    std::map<std::string, std::vector<int> > my_map;
    int first_value = 0;
    int result = std::accumulate(
                        my_map.begin(), 
                        my_map.end(), 
                        first_value,
                        map_value_adder<int, std::string, std::vector<int> >()
                     )
    Avec ce code, on va parcourir tous les vecteurs de la map, et consolider le contenu de chacune des cellules ce ces vecteurs pour obtenir une unique valeur result.

    Si ce n'est pas ce que tu veux, n'hésite pas à nous le dire.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 61
    Par défaut
    Ok, Emmanuel.
    Merci pour le tutoriel, je pense que ça me sera utile pour la suite.

    Cependant, en compilant, j'ai 2 erreurs;

    1 : cannot convert constant vector<int, allocation<int> >' to 'int' in 'int' initialisation.
    2 : main.cpp|31|error: invalid initialization of reference of type ‘std::vector<int, std::allocator<int> >&’ from expression of type ‘const int’|

    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
    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
     
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <numeric>
    #include <exception>
    #include <map>
     
    using namespace std;
     
    //Fonction pour faire la somme des éléments d'un map.
     
    template <class R, class A1, class A2>
    struct map_value_adder
    {
      R operator()(R prev, const std::pair<A1,A2>& value)
      {
        return prev + value.second;
      }
    };
     
    template <class A1, class A2>
            struct map_value_adder<typename std::vector<A2>::value_type, A1, std::vector<A2> >
            {
              typedef typename std::vector<A2>::value_type result_type;
     
              result_type operator()(result_type prev, const std::pair<A1,A2>& value)
              {
                std::vector<A2> & v = value.second;
                return std::accumulate(v.begin(), v.end(), prev);
              }
            };
     
    int main ()
    {
     
      // Creer mon tableau contenant les noms des èspéces et l'inserer dans un vecteur.
      const char* espece[] =
        { "homo_sapiens", "pan_troglodytes", "gorilla_gorilla", "pongo_pygmaeus",
    "macaca_mulatta", "callithrix_jacchus", "mus_musculus", "rattus_norvegicus",
    "canis_familiaris", "bos_taurus", "sus_scrofa", "equus_caballus" };
      set<string> especes;
      especes.insert (espece, espece + 12);
     
      ofstream fichier3 ("Alignement12Espces.txt", ios::out | ios::trunc);	// Fichier pour recuperer tous les alignements dans lesquels les 12 éspèces sont présentes.
      ifstream fichier ("Compara.12_eutherian_mammals_EPO.chr10_1.emf");	// ouvrir un fichier en lecture
      ofstream fichier2 ("information.txt", ios::out | ios::trunc);	// ouverture en écriture avec effacement du fichier ouvert
     
      if(not fichier)
        {
        // ce test échoue si le fichier n'est pas ouvert
        cerr << "fichier n'a pas pu être ouvert." << endl;
        throw exception();
        }
     
      map<string, vector<int> > tailles_marqueurs;
      map<string, map<string, int> > chromosome_sizes;
      //map<string, vector<int> > tailles_marqueurs;
     
      int n=0;//TODO Compteur de lignes
     
      // On saute les six premières lignes
      string part; // variable contenant chaque partie lue
      for(unsigned i=0; i<6; ++i)
        getline(fichier, part);
     
      while( getline(fichier, part, '/') )
        {
        if(part=="")
          continue;
     
        fichier2 << part << endl;
        fichier2 << "TOTO" << endl;
     
        stringstream partSS (part);
        string ligne;         // variable contenant chaque ligne lue
        while( getline(partSS, ligne) )
          {
          // {TODO
          ++n;
          //cout << "ligne " << n << " : " << ligne << endl;
          // TODO}
          if(ligne.substr(0,3) == "SEQ")
            {
            stringstream ligneSS (ligne);
     
            string espece;
            string id_chromosome;
            int debut_marqueur;
            int fin_marqueur;
            int sens;
            string taille_chr_string;
            int taille_chr;
     
            ligneSS >> espece; // "SEQ"
            ligneSS >> espece;
            ligneSS >> id_chromosome;
            ligneSS >> debut_marqueur;
            ligneSS >> fin_marqueur;
            ligneSS >> sens;
            ligneSS >> taille_chr_string;
     
            stringstream taille_chr_strstream (taille_chr_string.substr(12, taille_chr_string.size()-13));
            taille_chr_strstream >> taille_chr;
     
            int taille_marqueur = fin_marqueur - debut_marqueur;
            tailles_marqueurs[espece].push_back(taille_marqueur);
     
            chromosome_sizes[espece][id_chromosome] = taille_chr;
     
     
            }
          }
        }
        cout << "Il y a " << tailles_marqueurs["homo_sapiens"].size() << " marqueurs pour l'homme. Les tailles sont :" << endl;
          for(vector<int>::iterator m = tailles_marqueurs["homo_sapiens"].begin(); m != tailles_marqueurs["homo_sapiens"].end(); ++m)
            fichier2 << *m << " \t";
     
     
            int first_value = 0;
            int result = accumulate(
                                tailles_marqueurs.begin(),
                                tailles_marqueurs.end(),
                                first_value,
                                map_value_adder<int, string, vector<int> >()
                                   )
            fichier2 << result << endl;
     
    }
     
    Merci de votre aide!

  7. #7
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    J'ai fait une erreur d'innatention. Ca m'apprendra à ne pas vérifier mon code avant de le livrer

    En rouge barré, le code à supprimer ; en bleu, le code à rajouter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <class A1, class A2>
    struct map_value_adder<typename std::vector<A2>::value_type, A1, std::vector<A2> >
    {
    	typedef typename std::vector<A2>::value_type result_type;
    
    	result_type operator()(result_type prev, const std::pair<A1, A2 std::vector<A2> >& value)
    	{
    		const std::vector<A2> & v = value.second;
    		return std::accumulate(v.begin(), v.end(), prev);
    	}
    };

    Accessoirement, tu devrais faire attention à l'indentation de ton code : une bonne identation simplifie nettement sa lecture, et donc la compréhension des problèmes (après, je te le concède, les erreurs dur du code template deviennent vite incompréhensibles )
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 61
    Par défaut
    Merci pour la répone.

    Je vais tester le code pour voir si ça marche.
    Entre temps je l'ai fait plus simple et ça marche bien.

    Voici le 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
     
     
    // Pour  map<string, vector<int> > tailles_marqueurs;
     
     vector<int>& tailles_marqueurs_homme = tailles_marqueurs["homo_sapiens"];
        int SommeTailleMarqueurs = accumulate( tailles_marqueurs_homme.begin(), tailles_marqueurs_homme.end(), 0 );
     
     
     
    // Pour map<string, map<string, int> > chromosome_sizes;
     
       map<string, int> TailleChromosomeHomme = chromosome_sizes["h..."];
        int SommeTailleChromosomme = 0;
     
        for (map<string, int>::iterator mchr = chromosome_sizes["h..."].begin(); mchr != chromosome_sizes["h..."].end(); ++mchr)
        {
        SommeTailleChromosomme += (*mchr).second; // Somme 
        }
    Merci pour l'aide.

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

Discussions similaires

  1. [Débutant] Somme trois à trois des élements d'une matrice
    Par CSAM41 dans le forum MATLAB
    Réponses: 5
    Dernier message: 17/06/2013, 16h42
  2. faire la somme des montants d'une table
    Par nestam dans le forum Requêtes
    Réponses: 3
    Dernier message: 15/02/2007, 00h15
  3. Somme des résultats d'une requete
    Par Nathan dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 29/06/2006, 08h52
  4. Somme des résultat d'une requete
    Par Nathan dans le forum Langage SQL
    Réponses: 3
    Dernier message: 29/06/2006, 08h45
  5. Inserer des elements dans une map sans rangement ?
    Par Muetdhiver dans le forum C++
    Réponses: 3
    Dernier message: 07/09/2004, 11h09

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