在没有循环的 C++ 中移动数组元素
Posted
技术标签:
【中文标题】在没有循环的 C++ 中移动数组元素【英文标题】:Shift array elements in C++ without loop 【发布时间】:2016-11-26 10:48:36 【问题描述】:有没有一种方法可以在 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]
【问题讨论】:
std::rotate()
【参考方案1】:
C++ 标准算法也适用于数组,因此您只需使用 std::rotate
或 std::rotate_copy
。
不过,在您的 Python 示例中,函数的接口比旋转要复杂一些。作为第二个参数,您必须为将成为结果数组中第一个元素的元素提供一个迭代器。
对于数组 1, 2, 3, 4, 5
和一个元素的正向旋转,这将是第二个元素(“2”)。假设您使用std::array
或array + 1
,如果它是原始数组,则通过将1 加到数组的第一个元素的迭代器(例如array.begin() + 1
)来获得该元素的迭代器。
#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 em> 语法)都受支持,并且std::advance
使该函数适用于具有非随机访问迭代器的容器,例如std::list
(您必须重复递增迭代器以将它们推进多个元素)。
顺便说一句,如果你想支持大于或等于容器大小的n
参数,那么你可以使用C++17 函数std::size
或者只是创建你自己的。也许使用assert
来捕捉意外的否定论点:
assert(n >= 0);
using std::size;
n = n % size(container);
【讨论】:
以上是关于在没有循环的 C++ 中移动数组元素的主要内容,如果未能解决你的问题,请参考以下文章