在数组的开头添加一个元素并移动其余元素,但保留大小

Add an element at the beginning of an array and shift the rest but keep the size

本文关键字:元素 余元素 保留 移动 添加 数组 一个 开头      更新时间:2023-10-16

我需要按照以下格式创建一个向量/数组:

arr[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9 ,10]

我想在开头添加一个新元素,之后所有元素都向右移动并删除最后一个元素。结果应该是:

arr[10] = [new_int, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如何在 c++ 中执行此操作?我是否必须编写一个函数,或者已经有一个现有的函数,如 .append 或 .pushback?

如果是std::vector,简单的解决方案是:

vec.pop_back();
vec.insert(vec.begin(), new_int);

渐近复杂度与任何其他方法相同(pop_back()是O(1(,insert是O(n(,没有执行过重新分配(,但它无缘无故地暂时触及向量长度,并且总体上做了更多的记账。

一个更好的解决方案(对于std::vectorstd::array和C样式数组都很好(是:

std::copy_backward(std::begin(vec), std::end(vec)-1, std::begin(vec)+1);
vec[0] = new_int;

同样,这应该具有 O(n( 复杂性,但"偏移量"较小(它完全执行它需要做的事情,仅此而已(。


现在,如果我们转向不同的数据结构,情况就不同了;有了std::deque,你可以按照@JesperJuhl在他的回答中显示的那样做;在deque的两端推动/弹出成本摊销O(1(,所以对于大多数用途来说,它相当快。

不过,如果你的缓冲区大小是固定的,通常你描述的操作的自然数据结构是固定大小的循环缓冲区;它不是由标准库提供的,但在 Boost 中有一个实现(此外,自己编写它也是一个很好的练习,使用迭代器和所有东西(。

#include <algorithm>
#include <iterator>
...
std::rotate( std::begin(arr), std::end(arr)-1, std::end(arr));
arr[0] = new_int;

最简单的方法是使用std::deque。然后它变得像

my_deque.pop_back(); // get rid of last element.
my_deque.push_front(42); // put the new element at the front

您可以使用pushpopvector。如果你想使用数组来做到这一点,那么你可以:

int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
int new_value = 20;
for(int i(0); i < 10 - 2; i++){
arr[i + 1] ^= arr[i];
arr[i] ^= arr[i + 1];
arr[i + 1] ^= arr[i];
}

或者,您可以使用临时变量而不是运算符XOR

/*
int tmp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = tmp;
*/
arr[0] = new_value;
for(int i = 0; i < 10; i++)
std::cout << arr[i] << ", ";
std::vector<int> arr;
arr.insert(arr.begin(), newvalue);
arr.pop_back();