笔试面试4 字符串的循环移位算法

来源:互联网 发布:scihub 知乎 编辑:程序博客网 时间:2024/06/13 19:32

字符串的循环移位是指将整个字符串左移或者后移n位。

例如:ab1234左移两位就是1234ab.

这个算法的实现是利用三次反转。

仔细观察发现,左移和后移后,1234和ab的顺序是不变的。

将1234和ab看成两个整体。

左移可以通过以下变换得到。

先将ab反转,得到ba1234;

然后反转另一部分,1234,得到ba4321;

最后将整个反转,就得到了1234ab,即左移两位后的字符串。

代码实现为:(限定n的值为合法值,即n>=0&&n<strlen(str))

#include <stdio.h>#include <conio.h>#include <string.h>//例如   123abc 左移两位变为 3abc12 //核心思想:将str看成两部分,12和3abc,利用三次反转完成左移 // 左移后,这两部分都是不变的。//先将12反转,变为21;//反转3abc,变为cba3,这时候,源字符串变为了 21cba3//这时候,再将整个串反转,变为了3abc21,完成左移 char *rotate_left(char *str,int n){//循环左移,str为原串,n为左移位数  if(str==NULL)    return NULL; int len=strlen(str); int i;//C99 不允许在for内声明  for(i=0;i<n-1-i;i++){//reverse first part  str[i]=str[i]^str[n-1-i];  str[n-1-i]=str[i]^str[n-1-i];  str[i]=str[i]^str[n-1-i]; } int j; for(i=0,j=n;j<len-1-i;j++,i++){//reverse second part  str[j]=str[j]^str[len-1-i];   str[len-1-i]=str[j]^str[len-1-i];    str[j]=str[j]^str[len-1-i];    } int k; for(k=0;k<len-1-k;k++){//reverse all  str[k]=str[k]^str[len-1-k];    str[len-1-k]=str[k]^str[len-1-k];    str[k]=str[k]^str[len-1-k]; } }int main(){ char str1[]="hello";//不要写成 char *str="hello",因为这样的话得到的是字符串常量 char str2[]="thanks123";char str3[]="carry"; printf("str1=%s\n",str1);rotate_left(str1,0);printf("rotate_left(str1,0);\n");printf("str1=%s\n\n",str1);printf("str2=%s\n",str2);rotate_left(str2,3);printf("rotate_left(str2,3);\n");printf("str2=%s\n\n",str2);printf("str3=%s\n",str3);printf("rotate_left(str3,5);\n");rotate_left(str3,5);printf("str3=%s\n\n",str3);  getch(); }
测试结果:




循环右移的思想是完全一样的。

#include <stdio.h>#include <conio.h>#include <string.h>char *rotate_right(char *str,int n){//循环左移,str为原串,n为右移位数  if(str==NULL)    return NULL; int len=strlen(str); int i;//C99 不允许在for内声明  for(i=0;i<len-1-i-n;i++){//reverse first part  str[i]=str[i]^str[len-n-i-1];  str[len-n-i-1]=str[i]^str[len-n-i-1];  str[i]=str[i]^str[len-n-i-1]; } int j; for(i=0,j=len-n;j<len-1-i;j++,i++){//reverse second part  str[j]=str[j]^str[len-1-i];   str[len-1-i]=str[j]^str[len-1-i];    str[j]=str[j]^str[len-1-i];    } int k; for(k=0;k<len-1-k;k++){//reverse all  str[k]=str[k]^str[len-1-k];    str[len-1-k]=str[k]^str[len-1-k];    str[k]=str[k]^str[len-1-k]; } }int main(){ char str1[]="hello";//不要写成 char *str="hello",因为这样的话得到的是字符串常量 char str2[]="thanks123";char str3[]="carry"; printf("str1=%s\n",str1);rotate_right(str1,0);printf("rotate_right(str1,0);\n");printf("str1=%s\n\n",str1);printf("str2=%s\n",str2);rotate_right(str2,3);printf("rotate_right(str2,3);\n");printf("str2=%s\n\n",str2);printf("str3=%s\n",str3);printf("rotate_right(str3,5);\n");rotate_right(str3,5);printf("str3=%s\n\n",str3);  getch(); }
测试结果:




——————————————————————————————————————————————————————————————————

//写的错误或者不好的地方请多多指导,可以在下面留言或者点击左上方邮件地址给我发邮件,指出我的错误以及不足,以便我修改,更好的分享给大家,谢谢。

转载请注明出处:http://blog.csdn.net/qq844352155

author:天下无双

Email:coderguang@gmail.com

2014-11-5

于GDUT

——————————————————————————————————————————————————————————————————






0 0
原创粉丝点击