count_until和accumulate_until的实现?

时间:2013-12-26 10:36:41

标签: c++ algorithm boost c++11 stl

给定输入序列,标准算法std::countstd::accumulate计算特定值的出现次数(或谓词匹配std::count_if)和给定关联操作的累积(sum,product,Boolean或/和,min / max,string concatenation等)。

如果想知道输入序列是否包含完全/至少/最多n次出现/匹配,或者累积到精确/至少/最多n的总和,该怎么办?蛮力方式是将std::countstd::accumulate的结果与目标n进行比较,但这会错过提前退出的机会计数或累积超过输入序列中途的目标。

一个人可以,例如将count_until设为

template<class InputIt, class T, class Pred>
auto count_until(InputIt first, InputIt last, const T& value, Pred pred)
{
    auto res = 0;
    for (; first != last; ++first)
        if (*first == value && pred(++res))
            break; // early exit if predicate is satisfied
    return std::make_pair(first, res); // iterator and value to allow continuation    
}

通过使用合适的谓词并与返回的计数进行比较,可以从中测试相等性/至少/最多。

问题

  • 是否可以使用现有标准算法的组合来编写count_until(类似于accumulate_until),可能与合适的Boost.Iterator结合使用?
  • 特别是,我在考虑find_if而不是accumulate_iterator,其中谓词将从迭代器中提取计数或总和。
  • count_untilaccumulate_until是否可以在未来版本的标准库中作为独立原语包含在内?

编辑:我认为最有用的方法是返回迭代器的std::pair和首次满足谓词的点数。这使用户可以继续迭代。

1 个答案:

答案 0 :(得分:6)

我在考虑std :: find_if与状态谓词的组合: (Pred是普通用户谓词。)

template<class InputIt, class T, class Pred>
typename iterator_traits<InputIterator>::difference_type
count_until(InputIt begin, InputIt end, const T& value, Pred pred)
{
    typename iterator_traits<InputIterator>::difference_type count = 0;
    auto internal_pred = [&count, &value, &pred](decltype(*begin) elem) {
        return elem == value && pred(++count);
    };

    std::find_if(begin, end, internal_pred);
    return count;
}

template<class InputIt, class T, class Pred>
T accumulate_until(InputIt begin, InputIt end, T value, Pred pred)
{
    auto internal_pred = [&value, &pred] (const T& t) {
        value += t;
        return pred(value);
    };
    std::find_if(begin, end, internal_pred);
    return value;
}