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したがって、ベクトル 1{0,1,2,3}、ベクトル 2{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

これが求められていることだと思います。抽出されたサブベクトルを含むaを使用するadjacent_find()のではなく、入力を手動で繰り返します。とても簡単です、IMO。vectorvector<vector<int>>

#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 に答える