Подтвердить что ты не робот

Как свернуть контейнер STL?

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

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

Стандартная STL не имеет такой функции. У вас есть Boost?

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

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

4b9b3361

Ответ 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);      
}