Partage
  • Partager sur Facebook
  • Partager sur Twitter

Faire le produit des éléments d'un vecteur

Sujet résolu
    10 février 2016 à 10:38:40

    Bonjour tout le monde,

                         Je cherche a faire le produit des éléments d'un vector en utilisant la fonction accumulate. Mais je ne trouve pas le bon résultats :

    Voici un exemple :

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    #include <functional>
    #include <numeric>
    using namespace std;
     
    int main()
    {
        vector<double> v;
        v.push_back(4.5);
        v.push_back(2.21);
        v.push_back(3.32);
        v.push_back(43.2);
    
    
    
         cout<<accumulate (v.begin(), v.end(),
                             1,                           // Valeur initiale
                             multiplies<double>())<< endl;
     
     return 0;
    }


    Je trouve 1123 au lieu de 1426,35168.

    Une autre petite question au passage comment on fait le produit entre les éléments i=a à i=b avec a<b

    -
    Edité par MEZI 10 février 2016 à 10:40:34

    • Partager sur Facebook
    • Partager sur Twitter
      10 février 2016 à 10:40:53

      c'est normal, le résultat de std::accumulate est déduit ici à partir de la valeur d'initialisation que tu lui donne, 1, qui est un entier.

      Donc il fait tous ces calculs sur des entiers, d'où la différence. (pour être tout à faire précis, il fait la multiplication en double, mais stocke à chaque fois le résultat temporaire dans un entier)

      un petit 1. suffit pour passer tout ça en double et ça devrait aller beaucoup mieux.

      -
      Edité par epso 10 février 2016 à 10:54:21

      • Partager sur Facebook
      • Partager sur Twitter
        10 février 2016 à 10:47:50

        epso a écrit:

        c'est normal, le résultat de std::accumulate est déduit ici à partir de la valeur d'initialisation que tu lui donne, 1, qui est un entier.

        Donc il fait tous ces calculs sur des entiers, d'où la différence. (pour être tout à faire précis, il fait la multiplication en double, mais stocke à chaque fois le résultat temporaire dans un entier)

        un petit 1. suffit pour passer tout ça en double et ça devrait aller beaucoup mieux (ou plus verbeux, tu peux spécifier le premier type template de std::accumulate).

        -
        Edité par epso il y a 2 minutes


        Merci epso, ok je comprend mieux. Et il y a un truc que j'arrive pas faire c'est faire le produit de l'élément i à j par exemple. Le code suivant ne marche pas :

        #include <iostream>
        #include <vector>
        #include <algorithm>
        #include <iterator>
        #include <functional>
        #include <numeric>
        using namespace std;
         
        int main()
        {
            vector<double> v;
            v.push_back(4.5);
            v.push_back(2.21);
            v.push_back(3.32);
            v.push_back(43.2);
        
        
        
             cout<<accumulate (v.begin()+0, v.begin()+2,           // de l'élément i=0 à j=2
                                 1.,                           // Valeur initiale
                                 multiplies<double>())<< endl; 
         
         return 0;
        }

        Le résultat me donne 9.945

        -
        Edité par MEZI 10 février 2016 à 10:57:11

        • Partager sur Facebook
        • Partager sur Twitter
          10 février 2016 à 10:50:23

          v.end()+2
          Cela correspond a quel element dans ton tableau ?
          • Partager sur Facebook
          • Partager sur Twitter
            10 février 2016 à 10:55:18

            gbdivers a écrit:

            v.end()+2

            Cela correspond a quel element dans ton tableau ?


            Mdr (j'ai corrigé) je voulais dire  

            v.begin()+2

            Mais je n'ai tjrs pas le bon résultat

            -
            Edité par MEZI 10 février 2016 à 10:57:49

            • Partager sur Facebook
            • Partager sur Twitter
              10 février 2016 à 11:02:57

              Pourtant, 9.945 correspond bien au produit (4.5 * 2.21).

              N'aurais tu pas "oublie" que les paires d'iterateurs forment un interval ouvert a droite ? (http://guillaume.belz.free.fr/doku.php?id=iterateurs#intervalle_semi-ouvert)

              • Partager sur Facebook
              • Partager sur Twitter
                10 février 2016 à 11:05:05

                En faite , pour faire le produit des éléments de 1 à 2  je dois faire :

                     cout<<accumulate (v.begin()+1, v.begin()+3,
                                         1.0,                           // Valeur initiale
                                         multiplies<double>())<< endl;


                Je trouve cela bizarre que la deuxieme valeurs de accumulate soit exlu     

                Résultat=2.21*3.32=7,3372

                • Partager sur Facebook
                • Partager sur Twitter
                  10 février 2016 à 11:09:30

                  gbdivers a écrit:

                  Pourtant, 9.945 correspond bien au produit (4.5 * 2.21).

                  N'aurais tu pas "oublie" que les paires d'iterateurs forment un interval ouvert a droite ? (http://guillaume.belz.free.fr/doku.php?id=iterateurs#intervalle_semi-ouvert)


                  Je viens juste de m'en apercevoir.

                  Merci pour votre aide. Je trouve cela super l'entraide dans ce forum Merci merci !

                  • Partager sur Facebook
                  • Partager sur Twitter
                    10 février 2016 à 12:18:09

                    C'est la norme pour tous les algos de la STL pourtant, pas trop le choix^^
                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 février 2016 à 14:47:35

                      Salut,

                      MEZI a écrit:

                      Je trouve cela bizarre que la deuxieme valeurs de accumulate soit exlu     

                      Résultat=2.21*3.32=7,3372


                      En fait, c'est tout à fait normal, car un itérateur a la particularité de pouvoir représenter un élément invalide dans la collection dont il est tiré.  C'est ce qui permet de fournir un itérateur cohérent lorsque l'on appelle la fonction membre end() qui renvoie un itérateur sur... ce qui suit le dernier élément de la collection.

                      Si bien que, lorsque l'on écrit une boucle pour classique en utilisant les itérateurs, on peut écrire un code proche de

                      /* iterator est le type d'itérateur adéquat pour la collection
                       * que l'on utilise
                       */
                      for(iterator it = collection.begin(); it!=collection.end();++it){
                          /* on utilise l'itérateur ici */
                      }

                      sans risquer que collection.end() ne pose le problème d'avoir "un élément invalide à gérer".

                      Et, bien sur, à partir du moment où toutes les collections fournissent systématiquement une fonction permettant de récupérer ce qui suit le dernier élément valide, il devient "cohérent" faire en sorte que tous les algorithmes considère le dernier itérateur accessible comme... à ne pas utiliser ;)

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

                      Faire le produit des éléments d'un vecteur

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown