在阵列上执行移位操作的最佳方法

时间:2009-12-14 20:12:58

标签: c++ c

假设我有一个数组

unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9};

除了将它们全部复制到另一个数组之外,还有办法对它们执行移位操作。我们可以使用链接列表轻松完成它,但我想知道我们是否可以使用移位运算符并更快地完成工作。

注意:此问题中的数据只是一个示例。答案应该与数组中的数据无关。

6 个答案:

答案 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旋转,你:

  1. 就地反转第一个n元素,
  2. 就地反转其余元素,
  3. 就地整个阵列。
  4. 这需要一个额外存储元素(用于反转)。

    #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。