有没有实现条件累加的boost或stl函数?

Posted

技术标签:

【中文标题】有没有实现条件累加的boost或stl函数?【英文标题】:is there a boost or stl function that implements conditional accumulation? 【发布时间】:2014-04-21 11:55:37 【问题描述】:

我想实现将一个整数数组相加直到满足某个条件的代码。这是我的代码:

int x [5];

int GetIndex (int val)

    int i; 
    int xtotal=0; 

    for (i=0; i < 5; ++i) 
        if (xtotal > val) 
            break;
        xtotal += x [i];
    


    return i;    

我正在使用 c++03。我遇到了 stl 累积功能,但我不想把所有东西都加起来。我想将值相加,直到它大于输入。数组只是一个例子,可以用向量或其他东西代替。

【问题讨论】:

Implementations of count_until and accumulate_until? 的可能重复项 【参考方案1】:

你可以自己写。 这是来自http://www.richelbilderbeek.nl/CppAccumulate_if.htm的那个

template
   <
   typename InputIterator,
   typename ElementType,
   typename Predicate
   >
 const ElementType accumulate_if(
   InputIterator first,
   const InputIterator last,
   ElementType init,
   const Predicate predicate)
 
   for (; first != last; ++first)
     if (predicate(*first)) init += *first;
   return init;
 

他还有一个可以进行二元运算的,以防你除了加法之外还想做一些事情。

【讨论】:

所呈现的算法需要评估 所有 输入,无论是否使用该值。问题中的代码并不是真正的accumulate_if,而是accumulate_until(即一旦条件为真,循环终止)。除此之外,您应该避免返回 const 值,并且两个参数中的 const 也有点代码味道。如果算法不允许修改谓词,为什么要先复制?【参考方案2】:

你可以使用类似 (c++03):

template<class InputIt, class T>
std::pair<InputIt, T>
accumulate_until(InputIt begin, InputIt end, T value, T thresold_value)

    for (InputIt it = begin; it != end; ++it) 
        value += *it;
        if (thresold_value < value) 
            return std::make_pair(it, value);
        
    
    return std::make_pair(end, value);

或者更通用的解决方案(c++03):

namespace detail

    template <typename T, typename Pred>
    class InternalPredicate
    
    public:
        InternalPredicate(T& value, Pred& pred) : value(value), pred(pred) 

        bool operator () (const T& t) 
            value += t;
            return pred(value);
        
    private:
        T& value;
        Pred& pred;
    ;


template<class InputIt, class T, class Pred>
std::pair<InputIt, T>
accumulate_until(InputIt begin, InputIt end, T value, Pred pred)

    InputIt it = std::find_if(begin, end, detail::InternalPredicate<T, Pred>(value, pred));
    return std::make_pair(it, value);

或在 C++11 中:

template<class InputIt, class T, class Pred>
std::pair<InputIt, value>
accumulate_until(InputIt begin, InputIt end, T value, Pred pred)

    auto internal_pred = [&value, &pred] (const T& t) 
        value += t;
        return pred(value);
    ;
    InputIt it = std::find_if(begin, end, internal_pred);
    return std::make_pair(it, value);

【讨论】:

OP 使用的是 C++03 顺便说一句,所以没有 lambda 的版本可能会更好。另外,虽然我知道您的算法来自 TemplateRex 的问题,但我认为在这里使用原始循环是可以接受的,并且可能更简单(尤其是没有 lambda)。 @dyp:我同意通用 c++03 比简单循环或 c++11 的 lambda 更复杂:/ 我的意思是this;不确定如何考虑变异谓词(语言安全?) @dyp:您的示例在迭代器上使用谓词而不是在累积值上,因此可以将其重写为std::accumulate(begin, std::find_if(begin, end, pred), 0); m( 对,这是一个固定版本:coliru.stacked-crooked.com/a/421df53fa4f4268f accumulate 加上find_if 需要多遍。

以上是关于有没有实现条件累加的boost或stl函数?的主要内容,如果未能解决你的问题,请参考以下文章

向量中的累加函数(STL)给出负和

Spark 累加器

累加器与装载传送指令

Python 累加条件逻辑

052Java中使用do…while循环实现1~100的累加

051Java中使用while循环实现1~100的累加