Pages

Search This Blog

August 19, 2013

Rotate a vector of n elements by i

/**
 * from column 2 of Programming Pearls - Jon Bentley, Second Edition/
 * 
 * Rotate a one-dimensional vector of n elements by i positions. For instance
 * with n = 8 and i = 3, the vector abcdefgh is rotated to defghabc. Simple code
 * uses an n-element intermediate vector to do the job in n steps. Can you rotate
 * the vector in time proportional to n using only a few dozen extra bytes of storage?
 * 
 * analyzing the problem by hand shows that any resultant position for an element after rotation
 * can be boiled down to a formula (n+(x-i))%n, x is the current position of the element.
 * This tells to which cell any element moves to after the complete rotation is done.
 * The point to note here, applying above formula results in 
 * 1 or 2 or i distinct paths of such swaps which will result in end result.
 * more in code ...
 */

#include <iostream>

int main()
{
    char a[] = "ABCDEFGHIJKLMNOPQRT";
    int n = sizeof(a)/sizeof(char)-1;

    int i = 17;
    int n_pass = (n%2 == 1) ? 1 : ((n%i) == 0 ? i : ((i%2) == 0 ? 2 : 1));

    std::cout << "before: " << std::endl;
    for(int j = 0; j < n; j++)
        std::cout << a[j] << std::endl;

    for(int k = 0; k < n_pass; k++)
    {
        int x = k;
        char at_x = a[x];
        int to;
        do
        {
            to = (n+(x-i))%n;
            char t = a[to];
            a[to] = at_x;
            x = to;
            at_x = t;
        }while(to != k);
    }

    std::cout << "after: " << std::endl;
    for(int j = 0; j < n; j++)
        std::cout << a[j] << std::endl;
}

No comments:

Post a Comment