数组(通字符串)循环左(右)移的三种算法


1. 从后向前传递
template <typename Ntype>
Ntype Gcd(Ntype a, Ntype b)
{
    if (a < b)
        std::swap(a, b);

    while (b != 0)
    {
        auto temp = a % b;
        a = b;
        b = temp;
    }

    return a;
}

void leftshift_forward( int* array, int n, int shiftCount)
{
    int loop = Gcd(n, shiftCount);

    for (int i=0; i<loop; ++i)
    {
        auto temp = array[i];

        int j = i;
        while (true)
        {
            int next = (j + shiftCount) % n;

            if (next == i)
                break;

            array[j] =  array[next];

            j = next;
        }

        array[j] = temp;
    }
}

2. 替换
void leftshift_switch_1(int *array, int begin,int end, int dividePos)
{
    // p => p1, p2
    // p1 = [begin, dividePos)  , p2 = [dividePos, end]
    // p1, p2 => pd1, pd2, pd3,
    // swapcount = min(len(p1), len(p2))
    // pd1 = [begin, begin+swapcount), pd2 = [begin+swapcount, end - swapcount], pd3= (end-swapcount, end]
    // swap pd1, pd3 => pd3, pd2, pd1
    // len(p1) < len(p2) => continue switch pNext = pd3, pd2, KEEP pd1
    // else => continue swtich pNext => pd2, pd1, KEEP pd3
    // until swapcount is zero.

    do
    {
        int swapCount = std::min(dividePos - begin, end - dividePos + 1);

        for (int i=0; i<swapCount; ++i)
        {
            std::swap(array[begin+i], array[end + 1 -swapCount+ i]);
        }

        if (swapCount == 0)
            break;

        if (dividePos - begin > end - dividePos + 1)
        {
            begin = begin + swapCount;
            dividePos = end - swapCount + 1;
        }
        else
        {
            end = end - swapCount;
            dividePos = begin + swapCount;
        }
    } while (true);
   
    //leftshift_switch_1(array, nextbegin, nextend, nextDividePos);
}

void leftshift_switch(int* array, int n, int shiftCount)
{
    leftshift_switch_1(array, 0, n-1, shiftCount);
}


3. 翻转
void leftshift_rotate_1(int *array, int begin,int end);

void leftshift_rotate(int* array, int n, int shiftCount)
{
    leftshift_rotate_1(array, 0, shiftCount-1);
    leftshift_rotate_1(array, shiftCount, n-1);
    leftshift_rotate_1(array, 0, n-1);
}

void leftshift_rotate_1(int *array, int begin,int end)
{
    int mid = (begin + end) /2;
    for (int i=begin; i<=mid; ++i)
    {
        std::swap(array[i], array[end-i + begin]);
    }
}


在本机跑1000000次的(10个数移3位)运行结果表示
3 better than 2 better than 1

posted @ 2012-07-06 15:26  Mimaoku  阅读(258)  评论(0)    收藏  举报