实现一个函数,可以左旋字符串中的k个字符。
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<Windows.h>
#pragma warning(disable:4996)
//方法一
void Left1(char *str, int len, int num)
{
assert(str);
assert(len > 0);
assert(num > 0);
num%=len; //有效左旋次数
while (num--){
//完成一次左旋
char c = *str;
int i = 0;
for (; i < len-1; i++) //i+1最大为len-1,所以i<len-1
{
str[i] = str[i + 1];
}
str[i] = c;
}
}
//方法二:分前后两部分,先将前半部分逆置,再将后半部分逆置,最后整体逆置
//eg: abcd1234 num=4
// abcd -> dcba 1234 -> 4321 dcba4321 -> 1234abcd
void Reverse(char *start, char *end)
{
while (start<end){
*start ^= *end;
*end ^= *start;
*start ^= *end;
start++;
end--;
}
}
void Left2(char *str, int len, int num)
{
assert(str);
assert(len > 0);
assert(num > 0);
num %= len; //有效左旋次数
char *mid = str + num - 1; //根据有效左旋次数将str分为前后两部分 下标从0开始
Reverse(str, mid);
Reverse(mid + 1, str + len-1);
Reverse(str, str + len-1);
}
//对于较短str可采用拼接双份查找子串
void Left3(char *str, int len, int num)
{
assert(str);
assert(len > 0);
assert(num > 0);
num %= len; //有效左旋次数
char *buf = (char*)malloc(2 * len + 1); //堆上开辟空间
strcpy(buf, str);
strcat(buf, str); //得到双倍串
strncpy(str, buf + num, len); //将左旋后的str取出来 buf+num指向拷贝开始,len拷贝长度
free(buf); //释放
buf = NULL;
}
int main()
{
int num=3;
char str[] = "ABCD";
int len = strlen(str);
printf("%s\n", str);
Left3(str,len,num);
printf("%s\n", str);
system("pause");
return 0;
}