假设我有一个数组
unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9};
除了将它们全部复制到另一个数组之外,还有办法对它们执行移位操作。我们可以使用链接列表轻松完成它,但我想知道我们是否可以使用移位运算符并更快地完成工作。
注意:此问题中的数据只是一个示例。答案应该与数组中的数据无关。
答案 0 :(得分:20)
如果您想要元素的循环移位:
std::rotate(&arr[0], &arr[1], &arr[10]);
......会做的。你需要#include算法标题。
答案 1 :(得分:9)
只要数组是可修改的,你可以使用memmove来移动它们(但不要错误地使用memcpy,因为memcpy不适用于重叠区域):
memmove(&arr[0], &arr[1], sizeof(arr) - sizeof(*arr));
(sizeof(arr) - sizeof(* arr)是数组中除1个元素之外的所有字符的大小。)
答案 2 :(得分:7)
如果你是唯一一个指向数组的人,只需增加指针并减少长度。
请记住在释放时保留原始指针。
答案 3 :(得分:6)
如果您正在寻找纯C解决方案,那么它包括一个驱动程序。结果很简单:按n
旋转,你:
n
元素,这需要一个额外存储元素(用于反转)。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
/* print an array */
static void print_array(unsigned char *arr, size_t n, const char *prefix)
{
size_t i;
if (prefix) {
printf("%s: ", prefix);
}
for (i=0; i < n; ++i) {
printf("%02x ", (unsigned int)arr[i]);
}
printf("\n");
}
/* reverse 'arr', which has 'narr' elements */
static void reverse(unsigned char *arr, size_t narr)
{
size_t i;
for (i=0; i < narr / 2; ++i) {
unsigned char tmp = arr[i];
arr[i] = arr[narr-i-1];
arr[narr-i-1] = tmp;
}
}
/* rotate 'arr' of size 'narr' by 'shift' */
static void rotate(unsigned char *arr, size_t narr, unsigned long shift)
{
reverse(arr, shift);
reverse(arr + shift, narr - shift);
reverse(arr, narr);
}
/* driver program */
int main(int argc, char *argv[])
{
unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9,10};
size_t narr = sizeof arr / sizeof arr[0];
unsigned long shift = 2;
if (argc > 1) {
char *eptr;
shift = strtoul(argv[1], &eptr, 0);
if (*eptr || errno == ERANGE) {
perror("strtoul");
return EXIT_FAILURE;
}
}
print_array(arr, narr, "before shift");
rotate(arr, narr, shift);
print_array(arr, narr, "after shift");
return EXIT_SUCCESS;
}
答案 4 :(得分:1)
如果你真的想要BLAZING速度,请查看带有进位操作的汇编程序。 http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate#Shift_With_Carry_Instructions 再加上一个循环,您可以在几毫秒内对数组进行位移。
答案 5 :(得分:0)
我想知道你是否应该使用std :: valarray。