2012-07-05 128 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

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

或使用'的std :: deque'和'.rotate(1)'成员函数。 – 2012-07-05 11:14:58

+4

@CharlesBeattie:'deque'没有'rotate'成员函数。 – 2012-07-05 11:28:06

+0

糟糕。我有一个有旋转的版本(std :: deque很慢)。 – 2012-07-05 11:53:51

3

的参数inserterase是迭代器,而不是指标:

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',人们会这么认为,不会是一个。事实上,对于那些廉价可复制元素少的容器,事实证明'vector'仍然更快。 (使用'vector '和'deque '完成的测量,大约有10个元素。)有点让我吃惊,但事情就是这样。 – 2012-07-05 11:31:06

+0

@JamesKanze:的确,我应该补充一些过早优化或不进行测量的常用声明。 – 2012-07-05 11:31:55

+0

在这种情况下...我会说,给定的使用,'std :: deque'应该是默认的容器---你在两端插入或删除。事实上,这是我最初使用的。由于我的使用处于关键位置,因此我最终最终对其进行了分析并尝试了其他解决方案。至少对我来说,有些令人惊讶的结果。在“deque”中额外的indirections等最终花费的不仅仅是复制几个POD。 – 2012-07-05 11:44:58

6

使用std::rotate的建议当然是完全正确的; 使用现有功能始终是首选解决方案,当可用 时。永远不要少,值得指出为什么你的解决方案 不起作用。标准库中的容器,如std::vector, 以迭代器的形式获取位置信息,而不是索引。编写操作的 惯用方法是:

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

(如果你没有C++ 11,这是很简单的写你自己的版本的prev 或者在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到移位1位