8

我正在解决一个问题,我必须从更大的向量创建子向量。如果向量中的元素是连续的,我必须创建这些元素的向量。如果存在不连续的元素,则创建该单个元素的向量。我的逻辑如下

vector<int> vect;
for (int nCount=0; nCount < 3; nCount++)
    vect.push_back(nCount);

vect.push_back(5);
vect.push_back(8);
vector<int>::iterator itEnd;

itEnd = std::adjacent_find (vect.begin(), vect.end(), NotConsecutive());

函子NotConsecutive如下

return (int first != int second-1);

所以我期待它std::adjacent_find会返回迭代器,以便我可以创建向量一{0,1,2,3}、向量二{5}和向量{8}。但我不确定是否有更简单的方法?

编辑:我忘了提到我 std::adjacent_find在一个循环中

while(itBegin != vect.end())
{
    itEnd = std::adjacent_find (vect.begin(), vect.end(), NotConsecutive());
    vector<int> groupe;
    if( std::distance(itBegin, itEnd) < 1)
    {

        groupe.assign(itBegin, itBegin+1);
    }
    else
    {
        groupe.assign(itBegin, itEnd);
    }

    if(boost::next(itEnd) != vect.end())
    {
       itBegin = ++itEnd;                           
    }
    else
    {
       vector<int> last_element.push_back(itEnd);
    }
}

这有什么意义吗?

4

3 回答 3

3

我认为这是所要求的。它不使用adjacent_find()但手动迭代包含提取的子向量的vector填充 a 。vector<vector<int>>这很简单,IMO。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> vect { 0, 1, 2, 3, 5, 8 };

    // List of subvectors extracted from 'vect'.
    // Initially populated with a single vector containing
    // the first element from 'vect'.
    //
    std::vector<std::vector<int>> sub_vectors(1, std::vector<int>(1, vect[0]));

    // Iterate over the elements of 'vect',
    // skipping the first as it has already been processed.
    //
    std::for_each(vect.begin() + 1,
                  vect.end(),
                  [&](int i)
                  {
                      // It the current int is one more than previous
                      // append to current sub vector.
                      if (sub_vectors.back().back() == i - 1)
                      {
                          sub_vectors.back().push_back(i);
                      }
                      // Otherwise, create a new subvector contain
                      // a single element.
                      else
                      {
                          sub_vectors.push_back(std::vector<int>(1, i));
                      }
                  });

    for (auto const& v: sub_vectors)
    {
        for (auto i: v) std::cout << i << ", ";
        std::cout << std::endl;
    }
}

输出:

0, 1, 2, 3,
5、
8、

请参阅http://ideone.com/ZM9ssk上的演示。

于 2013-07-03T14:07:54.490 回答
2

由于您的限制,std::adjacent_find您无法按照您想要的方式使用它。但是它仍然很有用。

可以做的是迭代集合,并std::adjacent_find在循环中使用最后一个返回的迭代器(或第一次调用的外部循环迭代器),直到它返回end。然后你将拥有一套完整的连续元素。std::adjacent_find然后从最后一次调用返回非结束迭代器的地方继续外循环。

于 2013-07-03T13:59:54.357 回答
1

老实说,我没有发现使用简单的手工循环而不是标准函数有任何明显的缺点:

void split(const std::vector<int> &origin, vector<vector<int> > &result)
{
  result.clear();
  if(origin.empty()) return;

  result.resize(1);
  result[0].push_back(origin[0]);

  for(size_t i = 1; i < origin.size(); ++i)
  {
    if(origin[i] != origin[i-1] + 1) result.push_back(vector<int>());
    result.back().push_back(origin[i]);
  }
}
于 2013-07-03T14:13:47.403 回答