如:
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;
}
这种方法应该是最优方案。