数组循环移动

  今天,又发现了一个经典算法!不得不感叹,人类真的是无比聪明的生物,在无限感慨的同时,将这个算法发表出来!与大家一起分享,还有无论你是学web开发还是java或者C++编程的,编程算法都是走向高级程序员的必经之路。就像我学PHP一样。

       在编程中,我们常遇到一种数组整体移位的问题,比如:把abcdefg123456右移6位,变成123456abcdefg;

       题目原型是这样,给你一个字符串数组a[999],字符串长度n,移动位数k,求移位之后的数组。通常我们会这样处理:

以下代码用C++实现。

 

/*****楚河***********************************我是分界线帅哥*********下面文字来自大熊-编程学习博客*********************/

void RightMove(char *a,int n,int k)

{

    int t = 0;

    k = k%n;

    while(k–)

    {

        t = a[n-1];

        for(int i = n-1;i>0;i–)

        {

            a[i] = a[i-1];

        }

        a[0] = t;

    }

}

/****汉界***************************************我是风骚的分界线****无视我吧***********************************/

如果用这个方法的话,复杂度是O(n^2);

 

现在我们再看例子:abcdefg123456右移6位,变成123456abcdefg;

我们发现abcdefg和123456移动前后都是一个整体,就是内部没改变……这个时候有人就想出了三次翻转算法;

 

第一次翻转abcdefg得到gfedcba 123456;

第二次翻转123456得到gfedcba 654321;

第三次翻转gfedcba654321得到……得到了我们最后的答案123456abcdefg;

是不是很霸气!

这个规律听说是这样被发现的,一个人在玩自己的手指的时候,他先把10个手指编号,然后翻转左手,再翻转右手,最后整体翻转,之后看到结果很诧异,就出现了这个算法……废话不多说,上代码!

 

以下代码用C++实现。

 

/*****楚河***********************************我是分界线帅哥*********下面文字来自大熊-编程学习博客*********************/

#include<iostream>

 

 

#include<string.h>

using namespace std; 

//翻转字符串

void revers(char *arr,int a,int b)

{

    while(a<b)

    {

        int temp = arr[a];

        arr[a] = arr[b];

        arr[b] = temp;

        a++;

        b–;

    }

}

 

 

//处理翻转条件

void movright(char *arr,int N,int K)

{

    K = K%N;

    revers(arr,0,N-K-1);

    revers(arr,N-K,N-1);

    revers(arr,0,N-1);

}

int main()

    char a[999];

    int K;

    cin>>a;

    cin>>K;

    movright(a,strlen(a),K);

    for(int i = 0;i<strlen(a);i++)

    {

        cout<<a[i]<<" ";

    }

    return 0;

}

/****汉界***************************************我是风骚的分界线****无视我吧***********************************/

如果用这个方法的话,复杂度是O(n);

这个算法还可以用在很多地方,就等着大家去创新了!

原文地址:https://www.cnblogs.com/beipiaoboy/p/3324468.html