题目:
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
目录
方法一:将要旋转的n个字符分别从首字符开始一个一个地移动到字符串末尾。
方法二:利用strcpy函数拷贝以及strncat函数拼接形成左旋后的字符串。
=========================================================================
在开始做题前,我们需要了解字符串左旋的规则。
字符串左旋转(也称为字符串左移)是将字符串中的字符向左移动指定的位置数,而被移出字符串边界的字符则重新从字符串的右侧开始出现。这个过程不改变字符串中字符的相对顺序。假设我们有一个字符串 "abcdefg"
和一个旋转因子 n
,左旋转操作意味着将字符串的前 n
个字符移动到字符串的末尾。
例子:
假设字符串为
"abcdefg"
,旋转因子n = 2
,表示要将字符串的前两个字符"ab"
移动到字符串的末尾。
- 记下
"ab"
。- 将
"cdefg"
左移填充到字符串开头,得到"cdefg"
。- 将步骤 1 中的
"ab"
拼接到末尾,得到"cdefgab"
。因此,
"abcdefg"
左旋转 2 个位置后得到的结果是"cdefgab"
。
=========================================================================
方法一:将要旋转的n个字符分别从首字符开始一个一个地移动到字符串末尾。
实现思路:此方法通过逐个将左旋转的 n
个字符移至字符串末尾来实现旋转。具体操作如下:首先确定旋转次数,比如左旋转两个字符则需操作两轮。我们使用临时变量 tmp
保存首字符,随后通过循环将后续字符前移一位。循环结束后,将 tmp
中保存的字符追加至字符串尾部。重复此过程,直至完成所有旋转。
#include <stdio.h>
#include <string.h>
void LeftRound(char* str,int k)
{
int len = strlen(str);
int time = k % strlen(str); //操作的次数
int i = 0;
for (i = 0; i < time; i++)
{
char tmp = str[0];//临时变量tmp储存第一个字符
int j = 0;
for (j = 0; j < len - 1; j++)//将第二个字符及以后字符往前移动一位
{
str[j] = str[j + 1];
}
str[j] = tmp;//将原本的第一个字符存放到字符串末尾
}
printf("%s\n", str);
}
int main()
{
char str[] = "abcde";
int k = 2;//左旋字符的个数
LeftRound(str,k);
return 0;
}
=========================================================================
方法二:利用strcpy函数拷贝以及strncat函数拼接形成左旋后的字符串。
在使用这个方法以前,我们需要先学习strcpy函数以及strncat函数。
strcpy函数
strcpy
函数用于将一个字符串复制到另一个字符串中。它是 C 标准库中的一个函数,定义在<string.h>
头文件中。strcpy
的原型如下:char *strcpy(char *dest, const char *src);
- dest:目标字符串的指针,用于存放复制过来的源字符串。必须足够大,以容纳源字符串并为终止的空字符(
\0
)留出空间。- src:源字符串的指针,该字符串会被复制到
dest
指向的位置。我们需要注意的是:src(源字符串)将会覆盖dest(目标字符串)中的所有内容。
strncat
函数
strncat
函数用于将一个字符串的前n
个字符追加到另一个字符串的末尾。它同样定义在<string.h>
头文件中,其原型如下:char *strncat(char *dest, const char *src, size_t n);
- dest:目标字符串的指针,
src
的内容将被追加到该字符串的末尾。- src:源字符串的指针,其内容的前
n
个字符(或直到遇到\0
为止)将被追加到dest
的末尾。- n:指定最多复制多少个字符到
dest
。我们需要注意:src(源字符串)并不会覆盖dest(目标字符串)中的内容。
实现策略:首先,创建一个临时数组作为左旋转字符串的存储空间。通过 strcpy
,将未旋转的部分直接复制到临时数组。接着,使用 strncat
添加旋转部分至临时数组尾端。最终,strcpy
将临时数组内容覆盖回原字符串,实现左旋转。
#include <stdio.h>
#include <string.h>
void LeftRound(char* str,int k)
{
int len = strlen(str);
int num = k % len;
char tmp[100] = { 0 };
strcpy(tmp, str + num);//将未旋转的字符串复制到临时数组中
strncat(tmp, str, num);//将旋转的字符串复制到临时数组的结尾
strcpy(str, tmp);//将临时数组的内容覆盖回原数组中
printf("%s", str);
}
int main()
{
char str[] = "abcde";
int k = 2;
LeftRound(str,k);
return 0;
}
=========================================================================
方法三:利用分三步逆序的方法得到左旋后的字符串。
策略概述:先分割字符串为左旋与保持原位的两段。接着,分别对这两部分执行逆序操作。最终,对整体字符串逆序以完成左旋转。
void Reverse(char* str, int start, int end)//执行逆序操作的函数,start和end确定逆序操作的范围
{
int left = start;
int right = end;
while (left < right)
{
char tmp = str[left];//使用临时变量储存其中一个值,以便进行交换
str[left] = str[right];
str[right] = tmp;
left++;
right--;
}
}
void LeftRound(char* str, int k)//执行左旋字符的函数
{
int len = strlen(str);
int num = k % len;
Reverse(str, 0, num - 1);//确定左旋字符的区间再逆序
Reverse(str, num, len - 1);//确定保持原位的字符的区间再逆序
Reverse(str, 0, len - 1);//将字符串整体逆序
printf("%s\n", str);
}
int main()
{
char str[] = "abcde";
LeftRound(str, 2);
return 0;
}
=========================================================================
结语:在探索字符串左旋转的旅程中,我们一起穿越了算法的森林,探索了从直观到巧妙的不同路径。每一种方法都像是一把钥匙,打开了解决问题的新大门。无论是通过直接移位、使用临时数组还是巧妙地运用逆序,每一步都加深了我们对字符串操作的理解。正如编程世界的多样性,没有唯一的解决方案,只有最适合当前情况的选择。希望这篇博客能为你的编程旅程增添一份灵感,让我们在代码的世界里继续探索、学习和创造。记住,每一个问题都是通往新知识的桥梁,勇敢地跨越它,享受编程带来的乐趣吧!