Optimal way to perform a shift operation on an array

前端 未结 6 1498
醉酒成梦
醉酒成梦 2021-02-20 08:00

Suppose I have an array

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

Is there a way to perform shift operation on them besides just copying them

6条回答
  •  天涯浪人
    2021-02-20 08:33

    If you're looking for a pure C solution, here it is, including a driver program. It turns out to be pretty simple: to rotate by n, you:

    1. reverse the first n elements in-place,
    2. reverse the remaining elements in-place, and
    3. reverse the whole array in-place.

    This requires one element worth of extra storage (for reversing).

    #include 
    #include 
    #include 
    
    /* 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;
    }
    

提交回复
热议问题