C ++,std :: list的左/右旋转

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++,std :: list的左/右旋转相关的知识,希望对你有一定的参考价值。

有没有办法如何使用std::rotate列表

std::list<int> v = { 0,7, 1,2 };

因为这些左/右旋转

std::rotate(v.begin(), v.begin() + 1, v.end());
std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());

为矢量工作?

std::vector<int> v = { 0, 7, 1, 2 };

一种可能的方法是将列表复制到向量

std::vector<int> u{ std::begin(v), std::end(v) };

反之亦然,但我发现它太“冗长”......直接轮换列表会导致以下错误:

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

谢谢你的帮助。

答案

调用的唯一语法问题

 std::rotate(v.begin(), v.begin() + 1, v.end());

std::list迭代器不模拟random access iteratorsbidirectional iterators。因此,您不能向它们添加或从中减去积分值。相反,像这样打电话给std::rotate

std::rotate(v.begin(), std::next(v.begin()), v.end());
std::rotate(v.rbegin(), std::next(v.rbegin()), v.rend());

在这里,std::next会增加你的迭代器,无论它满足什么样的概念。这就是为什么有时候首先使用它(在你的情况下,使用std::vector时)更好的原因,因为它增加了一个间接层,而不是someIterator + 1,你可以硬连接随机访问要求。

另一答案

你不能添加到std::list迭代器,因为它不是随机访问。但你可以增加它。这就是std::next为您做的事情:

void rot_slow( std::list<Item>& seq )
{
    std::rotate( seq.begin(), next( seq.begin() ), seq.end() );
}

但是,这个使用std::rotate的逻辑使用O(n)交换操作。

这是不必要的低效率。如果要旋转列表中O(n²)复杂度的所有项目。它很快变得很慢。

而只是拼接列表末尾的第一个项目:

void rot_fast( std::list<Item>& seq )
{
    seq.splice( seq.end(), seq, seq.begin() );
}

这使用0项交换,O(1)复杂度。

以上是关于C ++,std :: list的左/右旋转的主要内容,如果未能解决你的问题,请参考以下文章

我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片

我的C/C++语言学习进阶之旅解决使用algorithm库里面的sort函数的时候,编译报错:未能使函数模板“unknown-type std::less<void>::operator ()(代码片

包含std :: list的结构的c ++初始化[重复]

来自 initializer_list 的三元运算符 + C++11 构造函数

c ++预期的左大括号以及重新定义错误

C++ stl 集合或链表