[英]C++, left/right rotation of std::list
Is there any way how to use std::rotate
for the list 有没有办法如何使用
std::rotate
作为列表
std::list<int> v = { 0,7, 1,2 };
since these left/right rotations 因为这些左/右旋转
std::rotate(v.begin(), v.begin() + 1, v.end());
std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
work for the vector? 为矢量工作?
std::vector<int> v = { 0, 7, 1, 2 };
One possible way is to copy the list to the vector 一种可能的方法是将列表复制到向量
std::vector<int> u{ std::begin(v), std::end(v) };
and vice versa but I found it too "lengthy"... A direct rotation of the list leads to the following errors: 反之亦然,但我发现它太“冗长”......直接轮换列表会导致以下错误:
Error C2672 'std::rotate': no matching overloaded function found
Error C2676 binary '+': std::_List_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator
Thanks for your help. 谢谢你的帮助。
You can't add to std::list
iterator since it's not random access. 你不能添加到
std::list
iterator,因为它不是随机访问。 But you can increment it. 但你可以增加它。 And that's what
std::next
does for you: 那就是
std::next
为你做的事情:
void rot_slow( std::list<Item>& seq )
{
std::rotate( seq.begin(), next( seq.begin() ), seq.end() );
}
However, this logic, using std::rotate
, uses O(n) swap operations. 但是,这个逻辑使用
std::rotate
,使用O(n)交换操作。
That's needlessly inefficient. 这是不必要的低效率。 If you want to rotate through all items in the list that's O(n²) complexity.
如果要旋转列表中O(n²)复杂度的所有项目。 It quickly gets very slow.
它很快变得很慢。
Instead just splice the first item in at the end of the list: 而只是拼接列表末尾的第一个项目:
void rot_fast( std::list<Item>& seq )
{
seq.splice( seq.end(), seq, seq.begin() );
}
This uses 0 item swaps, O(1) complexity. 这使用0项交换,O(1)复杂度。
The only syntactical issue with the invocation 调用的唯一语法问题
std::rotate(v.begin(), v.begin() + 1, v.end());
is that std::list
iterators don't model random access iterators but bidirectional iterators . 是
std::list
迭代器不模拟随机访问迭代器而是双向迭代器 。 Therefore, you can't add or subtract integral values to/from them. 因此,您不能向它们添加或从中减去积分值。 Instead, call
std::rotate
like this 相反,像这样调用
std::rotate
std::rotate(v.begin(), std::next(v.begin()), v.end());
std::rotate(v.rbegin(), std::next(v.rbegin()), v.rend());
Here, std::next
increments your iterator, no matter what concept it satifies. 在这里,
std::next
增加你的迭代器,无论它满足什么概念。 That's why it's sometimes better to use it in the first place (in your case, when using a std::vector
), as it adds one level of indirection as opposed to someIterator + 1
, where you hard-wire the random access requirement. 这就是为什么有时候首先使用它(在你的情况下,当使用
std::vector
)更好的原因,因为它增加了一个间接级别而不是someIterator + 1
,在那里你硬连接随机访问要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.