在容器中查找多个相邻值

时间:2014-11-17 21:33:20

标签: c++ algorithm stl

我正在寻找一种算法,它为我提供了一个迭代器,用于在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?

3 个答案:

答案 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;
}

Live Demo

答案 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);
}

DEMO


这是一个想法:

  1. 构造相邻差异(并将第一个元素设置为0)。给出你的起始向量

    9   9   8   8   8   8   7   7   6   6   6 
    

    这会产生

    0   0  -1   0   0   0  -1   0  -1   0   0 
    
  2. 现在从后面开始计算0,只要你找不到非零值。在那种情况下重置计数器。这给出了:

    2   1   4   3   2   1   2   1   3   2   1
    
  3. 接下来,使用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);
}

DEMO