Как сложить контейнер STL? - PullRequest
       8

Как сложить контейнер STL?

26 голосов
/ 11 октября 2010

Мне нужен аналог функции Haskell foldl для складывания любых контейнеров STL.Ожидаемая подпись выглядит следующим образом:

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

Стандартный STL не имеет такой функции.Есть ли у Boost какие-либо?

Я знаю, что это довольно просто реализовать, но я хотел бы знать, есть ли готовая стандартизированная реализация.

И еще один вопрос:как вы обычно складываете списки данных в C ++ / STL?

Ответы [ 5 ]

41 голосов
/ 11 октября 2010

STL имеет такую ​​функцию: std::accumulate. Однако это в заголовке <numeric>, а не <algorithm>.

На самом деле на странице Википедии в «Fold» уже перечислены функции foldl / foldr на большинстве языков программирования, включая C ++.

5 голосов
/ 11 октября 2010

Вы смотрели на std :: накопить в заголовке <numeric>?

1 голос
/ 07 января 2015

вот моя реализация, использующая std :: аккумулят

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 означает сгиб в Хаскеле.И этот шаблон функции может сделать программу более функциональной:)

0 голосов
/ 20 марта 2015

почему не просто;

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);      
}
0 голосов
/ 12 октября 2010

Хотя std:: accumulate кажется лучшим кандидатом, я думаю, что требование может быть достигнуто с помощью старого доброго for_each.

Я взял примеры по ссылке в ответе KennyTM и перевел их все до for_each. Полный код выложен на кодовой панели , ниже приводится выдержка:

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_ );
...