我正在寻找一种算法,它为我提供了一个迭代器,用于在STL容器内定义一些相邻的相等值。
这样的事情:
#include <algorithm>
std::vector<int> values = { 9, 9, 8, 8, 8, 8, 7, 7, 6, 6, 6 };
auto it = std::adjacent_find(values.begin(), values.end(), 4);
// Here I expect it pointing to the first '8' in above vector
当然,adjacent_find不会以这种方式工作,并且仅限于两个相邻的值。
同样search_n
对我没有帮助,因为我不想定义我要查找的具体值,只是相邻相等值的数量。
我可以使用STL还是我需要定义自己的算法? 谷歌和stackoverflow搜索并没有给我带来任何好结果。只有这个问题与我要做的不同:How to find the biggest sequence of some number passed like parameter?
答案 0 :(得分:1)
标准库中没有consecutive_find()
算法。我在这里为你实现了一个(复杂性O(n)
):
template <class Iter>
Iter consecutive_find(Iter first, Iter last, std::size_t n)
{
Iter marker(first), lead(first);
std::size_t count(1);
while (lead != last)
{
lead = std::next(marker);
while ((lead != last) && (*marker == *lead))
{
++count;
++lead;
}
if (count == n)
{
if ((lead == last) || !(*lead == *marker))
return marker;
++lead;
}
marker = lead;
count = 1;
}
return last;
}
答案 1 :(得分:1)
以下是您要求的功能的实现。它可能不是最快的,但它有效:
template<class InputIt>
InputIt repetition_find(InputIt first, InputIt last, size_t repetitions)
{
std::vector<int> temp;
std::adjacent_difference(first, last, std::back_inserter(temp));
temp.front()=0;
int count=0;
std::for_each(temp.rbegin(), temp.rend()
, [&](auto& a) { if(a==0) a = ++count; else {a=++count; count=0;}} );
auto diff = std::find_if(temp.begin(), temp.end()
, [&](auto a) {return a>=repetitions;} ) - temp.begin();
return std::next(first, diff);
}
这是一个想法:
构造相邻差异(并将第一个元素设置为0)。给出你的起始向量
9 9 8 8 8 8 7 7 6 6 6
这会产生
0 0 -1 0 0 0 -1 0 -1 0 0
现在从后面开始计算0,只要你找不到非零值。在那种情况下重置计数器。这给出了:
2 1 4 3 2 1 2 1 3 2 1
接下来,使用std::find_if
搜索大于重复次数的数字(此处为4
),获取此值的位置,将其添加到输入迭代器first
并返回结果。
答案 2 :(得分:0)
这是另一个实现。
template<class Iter>
Iter adjacent_find_n(Iter first, Iter last, std::size_t n, std::size_t offset)
{
if( first == last )
return last;
if( offset > 1 ){
if(!(*first == *(first - 1))) {
offset = 1;
}
if( offset == n ){
return first-(n-1);
}
}
return adjacent_find_n(++first, last, n, ++offset);
}
template<class Iter>
Iter adjacent_find_n(Iter first, Iter last, std::size_t n)
{
return adjacent_find_n(first, last, n, 1);
}