将向量中的结构成员求和 [英] Summing struct members inside a vector

查看:132
本文介绍了将向量中的结构成员求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下内容:

  typedef struct {
int a;
int b;
int c;
int d;
} ABCD;

typedef std :: vector< ABCD> VecABCD;

说我想在VecABCD类型的向量中加上每个'a'简单!

  int CalcSumOfA(const VecABCD& vec)
{
int sumOfA = 0;
VecABCD :: const_iterator it;
for(it = vec.begin(); it!= vec.end(); it ++)
sumOfA + = it-> a;
return sumOfA;
}

说我想用'b'做同样的事情吗?简单!我写....基本上相同的功能,但只有微不足道的变化。与'c'和'd'相同。



那么,有没有更简洁,更不重复的做法?我想做一些像:

  int sumOfA = SumOfMembers(myVec,a); 

但我不能想象我如何把这样的函数放在一起。理想情况下,它将是一个模板,我可以使用它与任何种类的结构的向量,而不是特定绑定到VecABCD。任何人都有任何想法?

解决方案

STL求和可以使用 std :: accumulate

  #include< functional> 

accumulate(v.begin(),v.end(),0,bind(plus< int>(),_1,bind(& ABCD :: a,_2)))

如果你想让这个更通用,你可以采取一个tr1 ::函数给你想要的成员bind:

  int sum_over_vec(const vector< ABCD>& v,const tr1 :: function< int(const ABCD& & member)
{
return accumulate(v.begin(),v.end(),
0,
bind(plus< int> b $ b _1,
bind(member,_2)));
};

// ...

int sum_a = sum_over_vec(vec,bind(& ABCD :: a,_1));






另一种方法,函数中的逻辑,将使用boost :: transform迭代器将逻辑放入迭代器中:

  tr1 :: function< int(const ABCD&)> member(bind(& ABCD :: a,_1)); 
accumulate(make_transform_iterator(v.begin(),member),
make_transform_iterator(v.end(),member),
0);

EDITED TO ADD:C ++ 11 lambda语法

使用C ++ 11 lambdas(尽管不幸不是更短)变得更清楚:

  accumulate(v.begin(),v.end(),0,
[](int sum,const ABCD& curr){return sum + curr.a});

  int sum_over_vec(const vector< ABCD>& v,const std :: function< int(const ABCD&)&>& member)
{
return accumulate(v.begin ),v.end(),0,
[&](int sum,const ABCD& curr){return sum + member(curr});});
};

用法:

 code> //使用从成员函数ptr到std :: function的转换。 
int sum_a = sum_over_vec(vec,& ABCD :: a);
//或者使用自定义λ求和的方块。
int sum_a_squared = sum_over_vec(vec,
[](const ABCD& curr){return curr.a * curr.a;});


Consider the following:

typedef struct {
    int a;
    int b;
    int c;
    int d;
} ABCD;

typedef std::vector<ABCD> VecABCD;

Say I wanted to add up every 'a' member in a vector of type VecABCD. Easy! I just loop through the vector, and sum as I go.

int CalcSumOfA(const VecABCD &vec)
{
    int sumOfA = 0;
    VecABCD::const_iterator it;
    for(it=vec.begin();it!=vec.end();it++)
        sumOfA += it->a;
    return sumOfA;
}

Say I wanted to do the same thing with 'b'? Easy! I'd write....essentially the same function, but with only trivial changes. Same with 'c' and 'd'.

So, is there a more concise, less repetitive way of doing this? I'd like to do something like:

int sumOfA = SumOfMembers(myVec, a);

but I can't conceive of how I'd put such a function together. Ideally, it'd be a template, and I could use it with a vector of any kind of structure, not specifically bound to VecABCD. Anyone have any ideas?

解决方案

STL summations can be done with std::accumulate

#include <functional>

accumulate(v.begin(), v.end(), 0, bind(plus<int>(), _1, bind(&ABCD::a, _2)))

If you wanted this to be more generic, you could take a tr1::function to the member you want to bind:

int sum_over_vec(const vector<ABCD>& v, const tr1::function<int (const ABCD&)>& member)
{
  return accumulate(v.begin(), v.end(),
                    0,
                    bind(plus<int>(),
                         _1,
                         bind(member, _2)));
};

// ...

int sum_a = sum_over_vec(vec, bind(&ABCD::a, _1));


Another way to do it, rather than putting your logic in the functor, would be to put the logic in the iterator, using a boost::transform iterator:

tr1::function<int (const ABCD&)> member(bind(&ABCD::a, _1));
accumulate(make_transform_iterator(v.begin(), member),
           make_transform_iterator(v.end(),   member),
           0);

EDITED TO ADD: C++11 lambda syntax

This becomes somewhat clearer with the C++11 lambdas (though unfortunately not shorter):

accumulate(v.begin(), v.end(), 0,
    [](int sum, const ABCD& curr) { return sum + curr.a });

and

int sum_over_vec(const vector<ABCD>& v, const std::function<int (const ABCD&)>& member)
{
  return accumulate(v.begin(), v.end(), 0,
      [&](int sum, const ABCD& curr) { return sum + member(curr}); });
};

Usage:

// Use a conversion from member function ptr to std::function.
int sum_a = sum_over_vec(vec, &ABCD::a);
// Or using a custom lambda sum the squares.
int sum_a_squared = sum_over_vec(vec,
    [](const ABCD& curr) { return curr.a * curr.a; });

这篇关于将向量中的结构成员求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆