26

我需要一个类似 Haskell 的foldl函数来折叠任何 STL 容器。预期的签名如下:

template Iterator, FoldingFunction, Result
Result foldl(
  Iterator begin, 
  Iterator end, 
  FoldingFunction f, 
  Result initValue);

标准 STL 没有这样的功能。Boost有吗?

我知道实现起来很简单,但我想知道是否有现成的标准化实现。

还有一个问题:您通常如何在 C++/STL 中折叠数据列表?

4

5 回答 5

43

STL 确实有这样一个功能:std::accumulate. 但是,它在 header<numeric>中,而不是<algorithm>.

实际上,“折叠”上的维基百科页面已经列出了大多数编程语言的foldl/foldr函数,包括 C++。

于 2010-10-11T13:49:23.833 回答
5

你看过标题中的std::accumulate吗?<numeric>

于 2010-10-11T13:49:36.030 回答
1

这是我使用 std::accumulate 的实现

template<typename collection, typename operation>
typename collection::value_type reduce(collection col, operation op)
{
    return accumulate(col.begin(),  col.end(), typename collection::value_type(), op);
}

方法折叠在 reduce Haskell 中。而且这个功能模板可以让程序更实用:)

于 2015-01-07T18:28:34.637 回答
0

虽然std:: accumulate似乎是最好的候选人,但我认为使用 good oldfor_each也可以达到要求。

我从KennyTM 的答案中的链接中获取了示例,并将它们全部翻译为for_each. 完整代码发布在 codepad,以下是一些摘录:

struct result_functor {
    result_functor( int initial, int multiplier ) :
        result_( initial ), multiplier_( multiplier ) {
    }
    int operator()( int x ) {
        result_ += multiplier_ * x;
        return result_;
    }
    int result_;
    int multiplier_;
};

const int init = 100;
const int numbers[] = { 10, 20, 30 };

const int accum_sum = std::accumulate( numbers, numbers + 3, init );
const result_functor for_sum = for_each( 
    numbers, numbers + 3, result_functor( init, +1 ) );
assert( accum_sum == for_sum.result_ );
于 2010-10-11T23:54:46.647 回答
-1

为什么不只是;

b_t foldl(b_t (*f)(b_t,a_t),b_t base_case,a_t * in_list){
 int l = sizeof(inList)/sizeof(a_t);
 b_t carry = base_case;
 for(int i = 0;i<l;i++){
   carry = f(carry,in_list[i]);
  }
 return carry;
}

或递归;// 也许你可以帮助我正确的语法...

b_t foldl(b_t (*f)(b_t,a_t),b_t base_case,a_t * in_list){
 return foldl(f,f(base_case,in_list[0]),in_list + 1);      
}
于 2015-03-20T13:53:24.480 回答