赞
踩
题目:实现一个函数,可以实现字符串的左旋
例如:ABCD左旋一个字符就是BCDA;ABCD左旋两个字符就是CDAB;
1.确定目标旋转k个字符,我们要获取字符串的长度 len,目的是根据长度来处理 k 可能超出字符串长度的情况;
2.创建一个函数 left 来实现字符串左旋;
3.对k进行取模运算:k%=len,该表达式目的是计算实际旋转次数。假设字符串长度是 5,而要左旋 7 个字符,实际上相当于左旋 7 % 5 = 2 个字符。
4.创建一个临时数组 temp 来存放要左旋的 k 个字符,防止后续移动字符串时数据丢失。
5.使用 strncpy 将字符串前 k 个字符复制到 temp 中,使用 memmove 函数移动字符串,把从第 k
个字符开始的部分向前移动 k
个位置。(等会简单介绍一下函数的使用)
6.使用 strncat 函数将保存在 temp 中的前 k
个字符拼接到移动后的字符串后面,完成左旋操作。
注:这里就简单介绍一下用法,能让大家读懂我后面写的代码,后面会专门出一篇文章来介绍这些函数。以下介绍的函数使用都需要加上头文件<string.h>
1、strncpy
strncpy是字符串复制函数,作用是将指定数量的字符从源字符串复制到目标字符串。
函数原型:char *strncpy(char *dest, const char *src, size_t n)
使用:
- #include <stdio.h>
- #include <string.h>
- int main() {
- char dest[10];
- char src[] = "Hello";
- strncpy(dest, src, 2); // 复制 src 的前 2 个字符到 dest
- dest[2] = '\0'; // 手动添加字符串结束符
- printf("%s\n", dest); // 输出 "He"
- return 0;
- }
2.memmove
memmove是内存操作函数,作用是将 n个字节的数据从 src 所指向的内存区域复制到 dest 所指向的内存区域,可以处理源内存区域和目标内存区域重叠的情况,保证正确地复制数据。
函数原型:void *memmove(void *dest, const void *src, size_t n)
使用:
- #include <stdio.h>
- #include <string.h>
-
- int main() {
- char str[] = "HelloWorld";
- memmove(str + 5, str, 5);
- printf("%s\n", str);
- return 0;
- }
3.strncat
strncat是字符拼接函数,作用是将源字符串 scr 中的最多 n 个字符拼接到目标字符串 dest 的末尾,并在拼接后的字符串末尾自动添加字符串结束符 '\0'
函数原型:char *strncat(char *dest, const char *src, size_t n)(同上)
使用:
- #include <stdio.h>
- #include <string.h>
-
- int main() {
- char dest[20] = "Hello, ";
- char src[] = "World!";
-
- strncat(dest, src, 5); // 拼接 src 的前 5 个字符
-
- printf("%s\n", dest); // 输出 "Hello, World"
-
- return 0;
- }
- #include <stdio.h>
- #include <string.h>
- void left(char* str, int k)//完成字符左旋操作
- {
- int len = strlen(str);
- k %= len;//实际左旋次数
-
- char temp[2];//这里使用2表示是因为在vs2022上表达式必须含有常量值
-
- strncpy(temp, str, k);//复制要左旋的k个字符到临时数组temp中
-
- memmove(str, str + k, len - k);//移动字符串
- str[len - k] = '\0';//确保完整性
-
- strncat(str, temp, k);//将存储在 temp 中的前 k 个字符拼接到移动后的字符串后面
- }
- int main()
- {
- char str[] = "abcd";
- int k = 2;//左旋个数为2
- printf("左旋前:%s\n", str);
- left(str, k);//实现左旋操作的函数调用
- printf("左旋后:%s\n", str);
- return 0;
- }
char temp[2]这是由于vs2022不支持变长数组才这样写的代码,如果你所使用的编译器支持边长数组,可以改进一下代码
代码改进:
- #include <stdio.h>
- #include <string.h>
- void left(char* str, int k)
- {
- int len = strlen(str);
- k %= len;
- char temp[k];//变长数组
- strncpy(temp, str, k);
- memmove(str, str + k, len - k);
- str[len - k] = '\0';
- strncat(str, temp, k);
- }
- int main()
- {
- char str[] = "abcd";
- int k = 2;
- printf("左旋前:%s\n", str);
- left(str, k);
- printf("左旋后:%s\n", str);
- return 0;
- }
如果在支持变长数组,这样写代码会更加的方便,你只需要修改所输入k的值就可以实现左旋不同个字符,例如:输入k=1,左旋一个字符;输入k=2,左旋两个字符。
代码及注释:(这个是结合老师的讲解所写的)
- #include <stdio.h>
- // 左旋字符串函数
- void left(char* str, int k)
- {
- int len = 0; // 存储字符串长度
- char* p = str; //遍历字符串计算长度
- while (*p) // 计算字符串长度
- {
- len++;
- p++;
- }
- k %= len; // 实际左旋次数
- for (int i = 0; i < k; i++) // 进行左旋操作
- {
- char temp = *str; // 保存字符串要左旋的k个字符
- for (int j = 0; j < len - 1; j++) // 将字符串从第二个字符开始依次向前移动一位
- {
- *(str + j) = *(str + j + 1);
- }
- *(str + len - 1) = temp; // 将保存的k个字符放到字符串尾部
- }
- }
- int main()
- {
- char str[] = "ABCD";
- int k = 2;
- printf("左旋前: %s\n", str);
- left(str, k);
- printf("左旋后: %s\n", str);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。