如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
方法一:
解题思路:先找出怎么左旋一次,然后在左旋两次。在左旋的时候要考虑如果左旋次数太大的情况,如ABCD左旋21次,其实是左旋一次,所以左旋的次数要和字符串长度取余。
#include<stdio.h> #include<Windows.h> #include<assert.h> char *left_switch(char *str,int n) { assert(str); assert(n > 0); int len = strlen(str); int top = n%len; for (int i = 0; i < top;i++){ char first = str[0]; //先取出第一个 int j = 0; for (; j < len - 1;j++){ str[j] = str[j + 1]; } str[j]= first; //加到最后面 } return str; } int main(){ char str[] = "ABCD"; int n = 3; char *p = left_switch(str, n); printf("%s", p); system("pause"); return 0; }
方法二:
解题思路:如给一个字符串“abcdef”,要左旋四次变为:efabcd.
可以先把要左旋的逆置:dcbaef,然后在把剩下的逆置:dcbafe,然后整体逆置:efabcd。
#include<stdio.h> #include<Windows.h> #include<assert.h> void reveser(char *start,char *end) { assert(start); assert(end); while (start<end){ *start ^= *end; *end ^= *start; *start ^= *end; start++; end--; } } char *left_switch(char *str,int n) { assert(str); assert(n > 0); int len = strlen(str); int top = n%len; reveser(str,str+top-1); reveser(str+top,str+len-1); reveser(str,str+len-1); return str; } int main(){ char str[] = "abcdef"; int n = 4; char *p = left_switch(str, n); printf("%s", p); system("pause"); return 0; }
方法三:
解题思路:如字符串“abcdef”在重新拷贝一份重新申请内存存放:变成“abcdefabcdef”,当左旋n次时,去掉n以前的字符串,然后取从n开始往后长度为原始字符串长度len个的字符串。如上面旋转次数为4,则取:“abcd(efabcd)ef”括号里的字符串。
#include<stdio.h> #include<Windows.h> #include<assert.h> #include<String.h> char *left_switch(char *str,int n) { assert(str); assert(n > 0); int len = strlen(str); int top = n%len; char *buf = (char *)malloc(2 * len - 1); //开辟内存 if (!buf)return NULL; strcpy(buf,str); strcat(buf,str); strncpy(str, buf + top, len); free(buf); return str; } int main(){ char str[] = "abcdef"; int n = 4; char *p = left_switch(str, n); printf("%s", p); system("pause"); return 0; }这种方法应该是最优方案。