今天,又发现了一个经典算法!不得不感叹,人类真的是无比聪明的生物,在无限感慨的同时,将这个算法发表出来!与大家一起分享,还有无论你是学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);
这个算法还可以用在很多地方,就等着大家去创新了!