我正在尝试旋转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);
但我收到此错误:
错误 6 错误 C2664: 'std::_Vector_iterator<_Myvec> std::vector:: insert<_Tp>&>(std::_Vector_const_iterator<_Myvec>,_Valty)' : 无法将参数 1 从"int"转换为"std::_Vector_const_iterator<_Myvec>"
我该如何解决?
标准库中有一个std::rotate
算法:
std::rotate(ObjectToRotate.begin(),
ObjectToRotate.end()-1, // this will be the new first element
ObjectToRotate.end());
当然,使用std::rotate
的建议是完全正确的;在以下情况下,使用现有函数始终是首选解决方案可用。 无论如何,值得指出您的解决方案的原因没用。 标准库中的容器,如 std::vector
,以迭代器的形式获取仓位信息,而不是索引。 这编写操作的惯用方法是:
v.insert( v.begin(), v.back() );
v.erase( std::prev( v.end() ) );
(如果你没有C++11,那么编写自己的版本很简单的prev
. 或者在vector
的情况下,你可以只写v.end() -
1
。
insert
和erase
的参数是迭代器,而不是索引:
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
变慢。
使用 std::rotate
: http://en.cppreference.com/w/cpp/algorithm/rotate
James Kanze提出了一个绝佳的答案,即使用以下代码片段来旋转单个元素。要旋转 x 数量的项目,只需将以下代码放入循环中即可。
vec.insert( vec.begin(), vec.back() );
vec.erase( std::prev( vec.end() ) );
但是,如果您可以使用标准旋转功能,那将是您的最佳选择。下面的代码再次旋转x个项目,请参阅有关旋转的CPP文档,它们甚至提供了显示左右旋转的代码示例。:)
// simple rotation to the left
std::rotate(vec.begin(), vec.begin() + x, vec.end());
// simple rotation to the right
std::rotate(vec.rbegin(), vec.rbegin() + x, vec.rend());
用于将 [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 以移动 1 个位置