Using accumulate algorithm with a set of pairs

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • cesco

    Using accumulate algorithm with a set of pairs

    I have a set of pairs defined as follow:

    set< pair<UserEquipm ent*, double> > numberOfFreqSlo tsToAdd;

    and I need to iterate through all the elements of the set in order
    accumulate the second field of the pair (that is double). Is there any
    way I can use the algorithm accumulate to accomplish this?
    The following line of code

    double unit = accumulate( numberOfFreqSlo tsToAdd.begin() ,
    numberOfFreqSlo tsToAdd.end(), 0.0);

    of course, won't work. Can you suggest anything similar using the
    algorithm accumulate?

    Thanks
    Francesco

  • TB

    #2
    Re: Using accumulate algorithm with a set of pairs

    cesco sade:[color=blue]
    > I have a set of pairs defined as follow:
    >
    > set< pair<UserEquipm ent*, double> > numberOfFreqSlo tsToAdd;
    >
    > and I need to iterate through all the elements of the set in order
    > accumulate the second field of the pair (that is double). Is there any
    > way I can use the algorithm accumulate to accomplish this?
    > The following line of code
    >
    > double unit = accumulate( numberOfFreqSlo tsToAdd.begin() ,
    > numberOfFreqSlo tsToAdd.end(), 0.0);
    >
    > of course, won't work. Can you suggest anything similar using the
    > algorithm accumulate?
    >[/color]

    template <class InputIterator, class T, class BinaryOperation >
    T accumulate (InputIterator first, InputIterator last, T init,
    BinaryOperation binary_op);

    Where foreach element:

    init = binary_op(init, *first);

    --
    TB @ SWEDEN

    Comment

    • Daniel T.

      #3
      Re: Using accumulate algorithm with a set of pairs

      In article <1139774538.167 436.264440@z14g 2000cwz.googleg roups.com>,
      "cesco" <fd.calabrese@g mail.com> wrote:
      [color=blue]
      > I have a set of pairs defined as follow:
      >
      > set< pair<UserEquipm ent*, double> > numberOfFreqSlo tsToAdd;
      >
      > and I need to iterate through all the elements of the set in order
      > accumulate the second field of the pair (that is double). Is there any
      > way I can use the algorithm accumulate to accomplish this?
      > The following line of code
      >
      > double unit = accumulate( numberOfFreqSlo tsToAdd.begin() ,
      > numberOfFreqSlo tsToAdd.end(), 0.0);
      >
      > of course, won't work. Can you suggest anything similar using the
      > algorithm accumulate?[/color]

      I gave an answer to this in comp.learn.c-c++. Here I will give several
      answers:

      class Object { };

      int main() {
      typedef std::set<std::p air<Object*, double> > MySet;
      MySet mySet;

      double unit = accumulate(mySe t.begin(), mySet.end(), 0.0,
      plus_second<MyS et::value_type> () );
      }

      The 'plus_second' functor is defined as follows:

      template <typename Pair>
      struct plus_second :
      std::binary_fun ction<typename Pair::second_ty pe, Pair,
      typename Pair::second_ty pe>
      {
      typename Pair::second_ty pe operator()(
      const typename Pair::second_ty pe& x, const Pair& y ) const
      {
      return x + y.second;
      }
      };

      Or something slightly more generic:

      class Object { };

      int main() {
      typedef std::set<std::p air<Object*, double> > MySet;
      MySet mySet;

      double unit = accumulate(mySe t.begin(), mySet.end(), 0.0,
      apply_to_second <std::plus<doub le>, MySet::value_ty pe>());
      }

      Which uses something like (though I can't say I like the name much:)

      template < typename Op, typename Pair >
      class apply_to_second : std::binary_fun ction<
      typename Pair::second_ty pe, Pair, typename Pair::second_ty pe >
      {
      Op fn;
      public:
      typename Pair::second_ty pe operator()( const typename
      Pair::second_ty pe& x, const Pair& y ) const
      {
      return fn( x, y.second );
      }
      };

      Whether you use one of the above, the one I gave in the other group, or
      the simplest one:

      class Object { };

      typedef std::set<std::p air<Object*, double> > MySet;

      double fn(double x, const MySet::value_ty pe& y)
      {
      return x + y.second;
      }

      int main()
      {
      MySet mySet;

      double unit = accumulate(mySe t.begin(), mySet.end(), 0.0,
      ptr_fun(&fn));
      }

      Is up to you. I'll leave you with the XP mantra, "use the simplest thing
      that works, refactor mercilessly."

      --
      Magic depends on tradition and belief. It does not welcome observation,
      nor does it profit by experiment. On the other hand, science is based
      on experience; it is open to correction by observation and experiment.

      Comment

      • Maxim Yegorushkin

        #4
        Re: Using accumulate algorithm with a set of pairs


        cesco wrote:[color=blue]
        > I have a set of pairs defined as follow:
        >
        > set< pair<UserEquipm ent*, double> > numberOfFreqSlo tsToAdd;
        >
        > and I need to iterate through all the elements of the set in order
        > accumulate the second field of the pair (that is double). Is there any
        > way I can use the algorithm accumulate to accomplish this?
        > The following line of code
        >
        > double unit = accumulate( numberOfFreqSlo tsToAdd.begin() ,
        > numberOfFreqSlo tsToAdd.end(), 0.0);
        >
        > of course, won't work. Can you suggest anything similar using the
        > algorithm accumulate?[/color]

        You can use an iterator that gets a first or second pair's member for
        you.


        Comment

        • cesco

          #5
          Re: Using accumulate algorithm with a set of pairs

          I'm facing a similar problem: I need to transform the set of pairs by
          scaling the second element (that is a double) by a certain factor.

          The following line of code:
          // typedef set<pair<UserEq uipment*, double> SetOfFsDouble;
          // SetOfFsDouble numberOfFreqSlo tsToAdd
          transform(numbe rOfFreqSlotsToA dd.begin(), numberOfFreqSlo tsToAdd.end(),
          numberOfFreqSlo tsToAdd.begin() , f_gx(bind2nd(st d::multiplies<d ouble>(),
          unit), select2nd<SetOf FsDouble::value _type>()));

          reports the following error:

          1>c:\program files\microsoft visual studio 8\vc\include\al gorithm(650)
          : error C2679: binary '=' : no operator found which takes a right-hand
          operand of type 'double' (or there is no acceptable conversion)
          1> c:\program files\microsoft visual studio
          8\vc\include\ut ility(55): could be 'std::pair<_Ty1 ,_Ty2>
          &std::pair<_Ty1 ,_Ty2>::operato r =(const std::pair<_Ty1, _Ty2> &)'
          1> with
          1> [
          1> _Ty1=UserEquipm ent *,
          1> _Ty2=double
          1> ]
          1> while trying to match the argument list
          '(std::pair<_Ty 1,_Ty2>, double)'
          1> with
          1> [
          1> _Ty1=UserEquipm ent *,
          1> _Ty2=double
          1> ]

          while the following approach:

          transform(numbe rOfFreqSlotsToA dd.begin(), numberOfFreqSlo tsToAdd.end(),
          numberOfFreqSlo tsToAdd.begin() ,
          ::make_pair(sel ect1st<SetOfFsD ouble::value_ty pe>(),
          (bind2nd(std::m ultiplies<doubl e>(), unit),
          select2nd<SetOf FsDouble::value _type>())) );

          where I try to overcome the previous problem by creating a Pair to give
          back to the set, reports the following error:

          1>c:\program files\microsoft visual studio 8\vc\include\al gorithm(650)
          : error C2064: term does not evaluate to a function taking 1 arguments
          1> c:\program files\microsoft visual studio
          8\vc\include\al gorithm(685) : see reference to function template
          instantiation '_OutIt
          std::_Transform <std::_Tree<_Tr aits>::iterator ,_OutIt,_Fn1,st d::_Iter_random _helper<_Cat1,_ Cat2>::_Iter_ra ndom_cat>(_InIt ,_InIt,_OutIt,_ Fn1,_InOutItCat ,std::_Range_ch ecked_iterator_ tag)'
          being compiled
          1> with
          1> [
          1>
          _OutIt=std::_Tr ee<std::_Tset_t raits<std::pair <UserEquipmen t
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator,
          1> _Traits=std::_T set_traits<std: :pair<UserEquip ment
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>,
          1> _Fn1=std::pair< select1st<std:: pair<UserEquipm ent
          *,double>>,sele ct2nd<std::pair <UserEquipmen t *,double>>>,
          1>
          _Cat1=std::_Tre e<std::_Tset_tr aits<std::pair< UserEquipment
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator:: iterator_catego ry,
          1>
          _Cat2=std::_Tre e<std::_Tset_tr aits<std::pair< UserEquipment
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator:: iterator_catego ry,
          1>
          _InIt=std::_Tre e<std::_Tset_tr aits<std::pair< UserEquipment
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator,
          1>
          _InOutItCat=std ::_Iter_random_ helper<std::_Tr ee<std::_Tset_t raits<std::pair <UserEquipmen t
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator:: iterator_catego ry,std::_Tree<s td::_Tset_trait s<std::pair<Use rEquipment
          *,double>,SinrB asedWithoutPowe rScaling::Numbe rOfFrequencySlo tsComparison,st d::allocator<st d::pair<UserEqu ipment
          *,double>>,fals e>>::iterator:: iterator_catego ry>::_Iter_rand om_cat
          1> ]

          Do you have any suggestion on how to solve this problem?

          Comment

          • Maxim Yegorushkin

            #6
            Re: Using accumulate algorithm with a set of pairs


            cesco wrote:[color=blue]
            > I'm facing a similar problem: I need to transform the set of pairs by
            > scaling the second element (that is a double) by a certain factor.[/color]

            Use boost::transfor m_iterator for that.

            Comment

            Working...