一.题目
目录
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
二.做题思路
:可以看见旋转一个字符其实就是将这个字符往最后一个移动,其他不变
而在我们选择旋转几次也是个问题,但是请思考一下,如图第4次又转回来了,说明选择旋转的次数(k)%字符的总长度(len)就是旋转的字符的个数。
三.解决方法
(1)方法1 暴力枚举
ok 有了上面的思考过程,接下来是第一种做题方法
void reverse(char* start,int n)//start接收数组首地址,n为选择旋转字符个数
{
int len=strlen(start);
int i=0,j=0;
int time=n%len;//time 为需要旋转的个数 长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推
for(i=0;i<time;i++)//旋转总次数
{
char temp=start[0];//保存每次字符移动的第一个
for(j=0;j<len-1;j++)//单个字符需要移动数
{
start[j]=start[j+1];
}
start[j]=temp;//将最后一个赋值为第一个
}
}
例子.
如果想要旋转"ABCDE"字符串中7个字符,那么旋转次数为(time)=7%5(字符串长度)为2
进入循环后在第一次内循环结束时字符串变为"BCDEE"
所以有了start[j]=temp;将保存的字符A赋值给start[4]使得字符串变为"BCDEA "
依此类推即可知道答案
(2)方法2 复制拼接
这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?
当然可以,我们可以选择拼接法,一次到位:
先上代码
void reverse(char* p, int n)
{
char temp[256] = "\0";
int len = strlen(p);
int time = n% len;
strcpy(temp, p + time);
strncat(temp, p, time);
strcpy(p, temp);
}
在这个代码中运用到了strcpy函数与strncat函数strcpy及为copy,如strcpy(temp, p + time);就是将
(p + time)的字符串赋值给temp
strncat(被拼接的数组首地址,拼接的数组首地址,拼接个数)
而你也可能注意到了这里用到了一个temp来临时储存
最后再将这个值copy给p
这个图可以让你很好的理解
(3)方法3 规律法
根据规律 如果你想要左旋两个字符,那么你可以先将前面两个逆序,再将后面三个逆序,
然后再将整个字符串逆序即可解决
void reverse(char* p, int key);
void reverserange(char* p, int startrange,int endrange );
int main()
{
char str[20] = "ABCDE";
char str[20] = "EABCD";
int key=0;
scanf("%d",&key);
reverse(str,key);
printf("%s", str);
return 0;
}
void reverse(char* p, int key)
{
int len = strlen(p);
int time = key % len;//旋转个数
reverserange(p,0,time-1);
reverserange(p, time, len-1);
reverserange(p, 0, len - 1);//规律
}
void reverserange(char* p, int startrange,int endrange)
{
char* start = p + startrange;
char* end = p + endrange;
while (start < end)
{
char temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
void reverserange(char* p, int startrange,int endrange);首先这个是经典的字符串逆序,而我们只需要控制逆序的首地址与结束地址即可
由于精力有限,个人实力有限,如有问题请提出,大一新生请多包涵,一起加油!!!