给定输入序列,标准算法std::count
和std::accumulate
计算特定值的出现次数(或谓词匹配std::count_if
)和给定关联操作的累积(sum,product,Boolean或/和,min / max,string concatenation等)。
如果想知道输入序列是否包含完全/至少/最多n
次出现/匹配,或者累积到精确/至少/最多n
的总和,该怎么办?蛮力方式是将std::count
或std::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_until
和accumulate_until
是否可以在未来版本的标准库中作为独立原语包含在内? 编辑:我认为最有用的方法是返回迭代器的std::pair
和首次满足谓词的点数。这使用户可以继续迭代。
答案 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;
}