有没有办法在不使用任何循环的情况下在C ++中移动数组元素,如下面的Python代码,只需通过操作列表索引来移动列表的元素
def rotate(lst, n):
n = n % len(lst)
return lst[n:] + lst[:n]
> rotate([1,2,3,4,5], 1) # rotate forward
[2, 3, 4, 5, 1]
答案 0 :(得分:0)
C ++标准算法也适用于数组,因此您只需使用std::rotate
或std::rotate_copy
。
功能'但是,在Python示例中,接口比旋转要复杂一些。作为第二个参数,您必须提供一个迭代器,该元素将成为结果数组中的第一个元素。
对于数组{ 1, 2, 3, 4, 5 }
和一个元素的正向旋转,这将是第二个元素(" 2")。通过向数组的第一个元素(例如array.begin() + 1
)添加1,假设您使用std::array
或array + 1
(如果它)&#,您将获得该元素的迭代器39;原始阵列。
#include <iostream>
#include <algorithm>
#include <array>
int main()
{
std::array<int, 5> array = { 1, 2, 3, 4, 5 };
std::rotate(
array.begin(),
array.begin() + 1,
array.end()
);
for (auto&& element : array)
{
std::cout << element << "\n";
}
}
如果您想要Python代码中的接口,那么您可以将std::rotate
包装在您自己的函数中并提供int
参数。这也是一个很好的机会,通过创建一个可以与任何合适的容器一起使用的通用函数,使整个事物更可重用:
#include <iostream>
#include <algorithm>
#include <array>
#include <vector>
#include <list>
template <class Container>
void rotate(Container& container, int n)
{
using std::begin;
using std::end;
auto new_begin = begin(container);
std::advance(new_begin, n);
std::rotate(
begin(container),
new_begin,
end(container)
);
}
int main()
{
std::array<int, 5> array = { 1, 2, 3, 4, 5 };
rotate(array, 1);
std::vector<int> vector = { 1, 2, 3, 4, 5 };
rotate(vector, 3);
std::list<int> list = { 1, 2, 3, 4, 5 };
rotate(list, 2);
int raw_array[] = { 1, 2, 3, 4, 5 };
rotate(raw_array, 3);
// test output goes here...
}
请注意std::begin
和std::end
如何确保原始数组(使用 begin + N 语法)和容器类(使用 c.begin())两者都支持+ N 语法),std::advance
使函数适用于具有非随机访问迭代器的容器,如std::list
(必须重复递增迭代器以使其超过一个元素)。
顺便说一句,如果你想支持大于或等于容器大小的n
个参数,那么你可以使用C ++ 17函数std::size
或者只是创建你的拥有。也许使用assert
来捕捉意外的否定论点:
assert(n >= 0);
using std::size;
n = n % size(container);