一.前言
本文章将使用三种思路实现字符串的左旋(循环移动,截取和拼接,逆序反转)
二.题目要求
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
三.题目分析
1 循环移动
当我们需要将字符串左旋k个字符时,一种简单的思路是通过循环移动字符的位置来实现。
具体的步骤如下:
- 首先获取字符串的长度,并对k进行取模操作。这是因为如果k的值大于字符串的长度,可以通过取模操作将其转换为一个等效的较小值。例如,对于字符串"ABCD",左旋5个字符相当于左旋1个字符,因为多余的4次旋转会回到原始的状态。
- 使用一个外层循环控制左旋的次数,执行k次循环即可完成字符的左旋操作。
- 在每次循环内部,使用一个内层循环将字符串中的每个字符向前移动一位。从第一个字符开始,将它后面的所有字符依次向前移动一个位置,直到倒数第二个字符。最后,将原始字符串的第一个字符放置在末尾位置,完成一次循环。
- 重复执行步骤3,直到完成k次循环,即完成字符串的左旋操作。
这样,我们通过循环移动字符的位置,就能够实现字符串的左旋。在给定的例子中,字符串"ABCD"左旋2个字符,首先将"A"移到末尾得到"BCDA",然后再将"B"移到末尾得到"CDAB",最终得到结果"CDAB"。
#include <stdio.h>
#include <string.h>
void leftRotate(char *str, int k)
{
int len = strlen(str);
// 对k取模,避免多余的左旋操作
k %= len;
// 左旋k个字符
for (int i = 0; i < k; i++)
{
char temp = str[0];
for (int j = 0; j < len - 1; j++) //单次平移
{
str[j] = str[j + 1];
}
str[len - 1] = temp;
}
}
int main()
{
char str[] = "ABCD";
int k = 0;
printf("请输入左旋的次数 k == ");
scanf("%d",&k);
printf("原始字符串:%s\n", str);
leftRotate(str, k);
printf("左旋%d个字符后的字符串:%s\n", k, str);
return 0;
}
示例输出
这种方法虽然简单,但是比较繁琐,执行次数较多,接下来将展示其他思路
2.截取和拼接
截取和拼接方法是一种简单直观的字符串左旋实现方式。其基本思路可以分为以下几个步骤:
1.对于左旋k个字符,我们需要将前k个字符截取出来。这可以使用标准库函数strncpy来实现,它接受三个参数:目标字符串、源字符串以及要复制的字符数。
strncpy函数用于将指定长度的字符串复制到字符数组中
2.将剩余的字符截取出来。由于C语言中字符串是以null字符(‘\0’)结尾的,我们可以通过直接使用源字符串的指针进行偏移来获取剩余的字符。
3.我们将两部分截取的字符串进行拼接。这可以使用标准库函数strcat来实现,它接受两个参数:目标字符串和要追加的字符串。
字符串连接函数 strcat() 可以将两个字符串连接起来。该函数从源字符串的尾部开始复制字符,直到遇到 NULL
字符。然后,它将目标字符串的 NULL 字符替换为源字符串中遇到的 NULL 字符。
4.最后,我们将修改后的字符串复制回原始的字符串变量中,这可以使用标准库函数strcpy来实现。
strcpy()函数:是将一个字符串复制到另一块空间地址中 的函数,‘\0’是停止拷贝的终止条件,同时也会将 ‘\0’ 也复制到目标空间。
代码展示如下
#include <stdio.h>
#include <string.h>
void leftRotate(char *str, int k)
{
int len = strlen(str);
// 对k取模,避免多余的左旋操作
k %= len;
// 创建临时数组用于存储截取的前k个字符
char temp[256];//这里使用k+1最好,因为vs中不支持变长数组,故这里初始化了一个值
strncpy(temp, str, k);
temp[k] = '\0';
// 将剩余的字符覆盖原始字符串
strcpy(str, str + k);
// 拼接截取的前k个字符到末尾
strcat(str, temp);
}
int main()
{
char str[] = "ABCD";
int k = 0;
printf("请输入左旋的次数 k == ");
scanf("%d",&k);
printf("原始字符串:%s\n", str);
leftRotate(str, k);
printf("左旋%d个字符后的字符串:%s\n", k, str);
return 0;
}
3.逆序反转
除了前面提到的方法,还有一种巧妙的解法是使用字符串翻转的方式来实现字符串左旋,具体思路如下:
1.首先将字符串划分为两部分,即前k个字符和剩余的字符。
2.分别对这两部分进行翻转操作:
- 对前k个字符进行翻转。
- 对剩余的字符进行翻转。
3.最后对整个字符串进行翻转操作,此时前k个字符已经在最后,完成左旋操作。
举个例子,我们对“ABCD”进行两次左旋。
先将要左旋的前两个逆序(BACD),然后将后半段也逆序(BADC),最后整体逆序(CDAB)
下图为代码演示
#include <stdio.h>
#include <string.h>
void reverse(char *str, int start, int end)
{
while (start < end)
{
char temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}
}
void leftRotate(char *str, int k)
{
int len = strlen(str);
// 对k取模,避免多余的左旋操作
k %= len;
reverse(str, 0, k-1); // 前k个字符翻转
reverse(str, k, len-1); // 剩余的字符翻转
reverse(str, 0, len-1); // 整个字符串翻转
}
int main()
{
char str[] = "ABCD";
int k = 0;
printf("请输入左旋的次数 k == ");
scanf("%d",&k);
printf("原始字符串:%s\n", str);
leftRotate(str, k);
printf("左旋%d个字符后的字符串:%s\n", k, str);
return 0;
}
四.尾声
以上就是本文章的所有内容,如果大家有更好的方法,大家可以在评论区讨论或者私信给博主。