标准库中没有这样的算法。您可以手动编写一个,使用std::find_if
和std::find_if_not
来查找每个出现序列的开始和结束迭代器。我认为输出应该是一个std::pair<FwdIt,FwdIt>
范围。该算法在其输入上具有O(N)
复杂度。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <utility>
template<class FwdIt, class OutIt, class UnaryPred>
auto find_all_if(FwdIt first, FwdIt last, OutIt dst, UnaryPred pred)
{
while (first != last) {
auto next_b = std::find_if(first, last, pred);
if (next_b == last) break;
auto next_e = std::find_if_not(next_b, last, pred);
*dst++ = make_pair(next_b, next_e);
first = next_e;
}
return dst;
}
int main()
{
auto const v = std::vector<int> { 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1 };
using It = decltype(v.begin());
std::vector<std::pair<It, It>> r;
find_all_if(begin(v), end(v), std::back_inserter(r),
[](auto e) { return e == 1; }
);
for (auto&& e : r) {
std::cout << "[";
std::cout << std::distance(begin(v), e.first) << ", ";
std::cout << std::distance(begin(v), e.second) << "), ";
}
}
在C++14风格下的
实时示例(使用手动类型定义和函数对象来支持老旧的C++98),可根据输入打印
[0, 3), [4, 6), [8, 12)
。
std::partition_point
和std::stable_partition
来实现。 - P0WIEnumerable<T>
类型来表示序列,并且它可以在运算符/算法之间很好地组合。我仍在学习如何组合STL算法。对于某些类型的操作,似乎拥有一个begin/end对使得代码变得更冗长,但它确实更灵活。 - Drew Noakes