Как свернуть контейнер STL?
Мне нужен аналог функции Haskell foldl
, чтобы сбрасывать любые контейнеры STL. Ожидаемая подпись выглядит следующим образом:
template Iterator, FoldingFunction, Result
Result foldl(
Iterator begin,
Iterator end,
FoldingFunction f,
Result initValue);
Стандартная STL не имеет такой функции. У вас есть Boost?
Я знаю, что это довольно просто реализовать, но я хотел бы знать, есть ли готовая стандартизованная реализация.
И еще один вопрос: как вы обычно складываете списки данных в С++/STL?
Ответы
Ответ 1
У STL есть такая функция: std::accumulate
. Однако он находится в заголовке <numeric>
, а не <algorithm>
.
На самом деле страница Wikipedia на "Fold" уже перечисляла функции foldl
/foldr
на большинстве языков программирования, включая С++.
Ответ 2
Вы просмотрели std:: accumulate в заголовке <numeric>
?
Ответ 3
здесь моя реализация с использованием 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. И этот шаблон функции может сделать программу более функциональной:)
Ответ 4
Хотя 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_ );
Ответ 5
почему не просто;
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);
}