使用for_each的向量中每个元素的平方和

pie*_*fou 10 c++ vector stl-algorithm

由于for_each接受的函数只接受一个参数(向量的元素),我必须定义一个static int sum = 0 某处,以便在调用for_each后可以访问它.我觉得这很尴尬.有没有更好的方法(仍然使用for_each)?

#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;

static int sum = 0;
void add_f(int i )
{
    sum += i * i;

}
void test_using_for_each()
{
    int arr[] = {1,2,3,4};
    vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));

    for_each( a.begin(),a.end(), add_f);
    cout << "sum of the square of the element is  " << sum << endl;
}
Run Code Online (Sandbox Code Playgroud)

在Ruby中,我们可以这样做:

sum = 0
[1,2,3,4].each { |i| sum += i*i}   #local variable can be used in the callback function
puts sum    #=> 30
Run Code Online (Sandbox Code Playgroud)

请您展示更多示例for_each,通常如何在实际编程中使用(不只是打印出每个元素)?是否有可能使用for_each模拟'编程模式',如map和在Ruby中注入(或在Haskell中映射/折叠).

#map in ruby 
>> [1,2,3,4].map  {|i| i*i} 
=> [1, 4, 9, 16]

#inject in ruby 
[1, 4, 9, 16].inject(0)  {|aac ,i| aac +=i}  #=> 30
Run Code Online (Sandbox Code Playgroud)

编辑:谢谢大家.我从你的回复中学到了很多东西.我们有很多方法可以在C++中做同样的事情,这使得它有点难以学习.但它很有趣:)

moc*_*ocj 37

不,不要使用std :: accumulate()使用std :: inner_product().不需要仿函数.

#include <vector>
#include <numeric>

void main()
{
    std::vector <int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);

    int x = std::inner_product( v1.begin(), v1.end(), v1.begin(), 0 );
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是最佳答案? (4认同)

Kir*_*sky 21

使用std :: accumulate

#include <vector>
#include <numeric>

// functor for getting sum of previous result and square of current element
template<typename T>
struct square
{
    T operator()(const T& Left, const T& Right) const
    {   
        return (Left + Right*Right);
    }
};

void main()
{
    std::vector <int> v1;
    v1.push_back(1);
    v1.push_back(2);
    v1.push_back(3);
    v1.push_back(4);

    int x = std::accumulate( v1.begin(), v1.end(), 0, square<int>() );
    // 0 stands here for initial value to which each element is in turn combined with
    // for our case must be 0.
}
Run Code Online (Sandbox Code Playgroud)

您可以在很好的GMan的答案中模拟std :: accumulate ,但我相信使用std :: accumulate将使您的代码更具可读性,因为它是为此目的而设计的.你可以在这里找到更多的标准算法.

  • 你是对的.我刚刚检查过 - 标准不保证迭代器是std命名空间的一部分.只有反向迭代器才是`std`命名空间的一部分. (2认同)

GMa*_*ckG 7

for_each返回它正在使用的仿函数(的副本).所以,像这样:

#include <algorithm>
#include <vector>
#include <iostream>

template <typename T>
class square_accumulate
{
public:
    square_accumulate(void) :
      _sum(0)
      {
      }

      const T& result(void) const
      {
          return _sum;
      }

      void operator()(const T& val)
      {
          _sum += val * val;
      }

private:
    T _sum;
};

int main(void)
{
    int arr[] = {1,2,3,4};
    std::vector<int> a (arr ,arr + sizeof(arr)/sizeof(arr[0]));

    int sum = std::for_each(a.begin(), a.end(), square_accumulate<int>()).result();

    std::cout << "sum of the square of the element is " << sum << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

然而,正如其他答案所证明的那样,std::accumulate是最好的方法.

  • 这是std :: accumulate仿真的一个很好的例子.用于教学目的. (3认同)