jus*_*tik 3 c++ algorithm list vector rotation
有没有办法如何使用std::rotate
列表
std::list<int> v = { 0,7, 1,2 };
Run Code Online (Sandbox Code Playgroud)
因为这些左/右旋转
std::rotate(v.begin(), v.begin() + 1, v.end());
std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
Run Code Online (Sandbox Code Playgroud)
为矢量工作?
std::vector<int> v = { 0, 7, 1, 2 };
Run Code Online (Sandbox Code Playgroud)
一种可能的方法是将列表复制到向量
std::vector<int> u{ std::begin(v), std::end(v) };
Run Code Online (Sandbox Code Playgroud)
反之亦然,但我发现它太"冗长"......直接轮换列表会导致以下错误:
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
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
您无法添加到std::list
迭代器,因为它不是随机访问.但你可以增加它.那就是std::next
对你有用的东西:
void rot_slow( std::list<Item>& seq )
{
std::rotate( seq.begin(), next( seq.begin() ), seq.end() );
}
Run Code Online (Sandbox Code Playgroud)
但是,这个逻辑std::rotate
使用O(n)交换操作.
这是不必要的低效率.如果要旋转列表中O(n²)复杂度的所有项目.它很快变得很慢.
而只是拼接列表末尾的第一个项目:
void rot_fast( std::list<Item>& seq )
{
seq.splice( seq.end(), seq, seq.begin() );
}
Run Code Online (Sandbox Code Playgroud)
这使用0项交换,O(1)复杂度.
调用的唯一语法问题
std::rotate(v.begin(), v.begin() + 1, v.end());
Run Code Online (Sandbox Code Playgroud)
是std::list
迭代器不模拟随机访问迭代器而是双向迭代器.因此,您不能向它们添加或从中减去积分值.相反,称std::rotate
这样的
std::rotate(v.begin(), std::next(v.begin()), v.end());
std::rotate(v.rbegin(), std::next(v.rbegin()), v.rend());
Run Code Online (Sandbox Code Playgroud)
在这里,std::next
增加你的迭代器,无论它满足什么概念.这就是为什么有时候首先使用它(在你的情况下,当使用a时std::vector
)更好,因为它增加了一个间接级别,而不是someIterator + 1
硬连接随机访问要求.