2012-07-05 19 views
6

C++で要素のベクトルを回転しようとしています。私が意味することは、私がvector<point>を持っているということです。最後の要素が最初になりたいのです。ベクトル(配列)を回転する

例:

[1,2,3]となる[3,1,2]そのため、[2,3,1]

私は次の操作を実行しようとした:

//Add the last element at index 0 
ObjectToRotate.insert(0, ObjectToRotate.at(ObjectToRotate.size()-1)); 
//Remove Last element 
ObjectToRotate.erase(ObjectToRotate.size()-1); 

が、私はこのエラーを取得:

Error 6 error C2664: 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::insert<cv::Point_<_Tp>&>(std::_Vector_const_iterator<_Myvec>,_Valty)' : cannot convert parameter 1 from 'int' to 'std::_Vector_const_iterator<_Myvec>' 

どのように私はそれを解決することができますか?

答えて

13

std::rotate algorithmは、標準ライブラリにあります:inserterase

std::rotate(ObjectToRotate.begin(), 
      ObjectToRotate.end()-1, // this will be the new first element 
      ObjectToRotate.end()); 
+1

をシフトまたは 'のstd :: deque'と使用する1であります'.rotate(1)'メンバ関数です。 –

+4

@CharlesBeattie: 'deque'は' rotate'メンバ関数を持っていません。 –

+0

私は回転を持っているバージョンを持っています(std :: dequeは遅いです)。 –

3

引数はイテレータではなく、インデックスのとおりです。

ObjectToRotate.insert(ObjectToRotate.begin(), ObjectToRotate.back()); 
ObjectToRotate.pop_back(); // or erase(ObjectToRotate.end()-1), if you prefer 

しかし、再割り当ての可能性を回避するために、(コピーを取った後)最初の最後の要素を取り除くために、より効率的な場合があります

auto back = ObjectToRotate.back(); 
ObjectToRotate.pop_back(); 
ObjectToRotate.insert(ObjectToRotate.begin(), back); 

またはstd::rotateを使用する:

std::rotate(ObjectToRotate.begin(), ObjectToRotate.end()-1, ObjectToRotate.end()); 

あなたが」これを多くしてから、dequeは、両端で効率的に挿入したり取り外したりすることができるので、コンテナのより良い選択肢かもしれません。しかし、スピードが重要な場合は、これが本当に改善されているかを測定して確認してください。順序がそれほど大きくなければ、より複雑なメモリレイアウトからのオーバーヘッドにより、dequeが遅くなる可能性があります。

+0

Re 'deque'は、そうだと思います。実際、安価にコピー可能な要素がほとんどないコンテナでは、 'ベクトル 'はまだまだ高速です。 ( 'ベクトル'と 'deque 'で行われ、約10個の要素で測定されています)。私は驚いていますが、それはそうです。 –

+0

@JamesKanze:実際に、時期尚早に、または測定なしで、最適化に関する通常の免責事項を追加する必要があります。 –

+0

この場合...私は、使用すると 'std :: deque'がデフォルトのコンテナでなければならないと思います---両端で挿入または削除しています。実際、私が最初に使ったものです。私の使用が重要な場所にあったので、私は最終的にそれをプロファイリングし、他のソリューションを試してみました。少なくとも私にとっては、やや驚くべき結果でした。 'deque'の余分な迂回などは、いくつかのPODをコピーする以上のコストがかかります。 –

6

std::rotateを使用する推奨事項は、もちろん、完全に正しいです。 が利用可能な場合は、既存の機能を使用する が常に推奨されます。決して少なくても、あなたのソリューション が機能しなかった理由を指摘する価値があります。 std::vector, のような標準ライブラリのコンテナは、インデックスではなくイテレータの形で位置情報を取得します。あなたの書き込み動作の 慣用的な方法は、次のようになります。あなたがC++ 11を持っていない場合、それはあなた自身のバージョンprevの を書くことはかなり単純です(

v.insert(v.begin(), v.back()); 
v.erase(std::prev(v.end())); 

それともvectorの場合は、あなたv.end() - 1と書くことができます。

1

[1,2,3]を[2.3。1]ここでコードここで

vector<int> Solution::rotateArray(vector<int> &A, int B) { 
vector<int> ret; 
for (int i = 0; i < A.size(); i++) { 
    ret.push_back(A[(i + B) % A.size()]); 
} 
return ret; 

}

Aは[1,2,3]及びBが1つの位置

関連する問題