练习1:左旋字符
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
思路1:
分成k次左旋,每次左旋1个字符,
每次左旋将字符串第一个字符挪到最后面,剩余所有字符都往前移一位。可以使用双层循环:
外层循环,控制左旋的次数,每循环一次,左旋1个字符;
内层循环,控制字符串后面的sz-1个字符挪到第一个字符前面
注意:
(1)当左移次数超过数组大小时,我们可以减去重复的数组长度,简便计算。
例如长度为5的情况下,旋转6次相当于旋转1次,旋转7次相当于旋转2次,以此类推,可以发现每5次旋转后字符串相当于没有旋转。所以我们可以使用左移个数%=数组长度来简化计算。
代码如下:
#include <stdio.h>
#include <string.h>
RotateString(char* ptr, int k)
{
int i, j, tmp;
int sz = strlen(ptr);
k %= sz;
for (i = 0; i < k; i++)
{
tmp = ptr[0]; //先将第一个字符保存在变量tmp中
for (j = 0; j < sz - 1; j++)
{
ptr[j] = ptr[j + 1];
}
ptr[sz - 1] = tmp; //将第一个字符挪到最后面
}
}
int main()
{
char ch[100];
scanf("%s", ch);
printf("旋转前字符串为:%s\n", ch);
int k;
printf("输入需要左旋字符的个数:");
scanf("%d", &k);
RotateString(ch,k); //RotateString函数实现左旋k个字符
printf("旋转%d个字符后字符串为:%s\n", k, ch);
return 0;
}
思路2:
例如ABCDEFG,左旋3次后变成DEFGABC。
有一个特殊的操作方式:
先将要左旋的前三个字符逆序,得到(CBADEFG),
然后将后半段也逆序,得到(CBAGFED),
最后整体逆序,得到(DEFGABC)即可。
可以写一个函数帮我们完成局部逆序,将需要移位的字符串个数逆序,将其余的字符串逆序,最终将所有的字符串逆序输出。
局部逆序函数我们可以先提供需要逆序的数组的下标范围,然后依次将数组对称的两个字符进行交换
代码如下:
#include <stdio.h>
#include <string.h>
char* ReverseString(char* ptr, int start,int end)
{
while (start <= end)
{
char tmp = ptr[start];
ptr[start] = ptr[end];
ptr[end] = tmp;
start++;
end--;
}
return ptr;
}
int main()
{
char ch[100];
scanf("%s", ch);
printf("旋转前字符串为:%s\n", ch);
int k;
printf("输入需要左旋字符的个数:");
scanf("%d", &k);
int sz = strlen(ch);
k %= sz;
ReverseString(ch, 0, k-1); //将前面k个字符串逆序
ReverseString(ch, k, sz-1); //将剩余的sz-k个字符串逆序
ReverseString(ch, 0, sz - 1); //将整个字符串逆序
printf("旋转%d个字符后字符串为:%s\n", k, ch);
return 0;
}
结果如图:
练习2:逆序字符串
写一个函数,可以逆序一个字符串的内容。
思路:在函数中定义变量start指向数组第一个元素,end指向数组最后一个元素,用while循环来实现将start所指向的数组的值与end所指向的数组的值进行交换,并且在每次交换完之后将start和end指向的位置改变,start每次循环后指向数组下一个元素,end每次循环后指向数组前一个元素。
#include <stdio.h>
#include <string.h>
char* ReverseString(char* ptr, int sz) //每次将前后对称的字符互换
{
char* start = ptr;
char* end = ptr + sz - 1;
while (start <= end)
{
char tmp = *start;
*start = *end;
*end = tmp;
start++;
end--;
}
return ptr;
}
int main()
{
char ch[100];
scanf("%s",ch);
int sz = strlen(ch);
printf("逆序后字符串为:%s\n", ReverseString(ch, sz));
return 0;
}
结果如图:
以上两个题目只能实现一个字符串的左旋,例如输入i am中间有空格就无法实现,需要更改输入函数,把scanf函数换成fgets函数来实现。