字符串的左旋问题解析
来源:互联网 发布:澳洲导航软件 编辑:程序博客网 时间:2024/04/29 18:23
1.实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
第一种方法:
思路:先将一个字符串左移一位,可以使用一层for循环来实现,
然后每次都可以调用这层循环,调用移位的次数,还有就是,
循环次数如果大于字符串的长度,会重复执行一些无用的
操作,所以给step模上字符串的长度,就可以产生一个小于
字符串长度的数字。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>void str_shift(char *str,int len, int step){ int i = 0; int j = 0; char tmp = 0; step %= len;//step为0到(len - 1)的一个数字,提高了移位时的效率 assert(str); assert(len > 1); for (j = 0; j < step; j++)//外层循环实现左移step位 { tmp = str[0]; for (i = 0; i < len - 1; i++)//内层循环实现了左移一次 { str[i] = str[i+1]; } str[i] = tmp; }}int main(){ char msg[] = "ABCD1234"; int k = 0; printf("Please Enter:>"); scanf("%d",&k); printf("before : %s\n",msg); str_shift(msg,strlen(msg), k); printf("shift_after : %s\n",msg); system("pause"); return 0;}
第二种方法:
思路:将一个字符串从它要移位的位置分为两个部分,
(例如:字符串:ABCD1234 要移3位 则将其分为 ABC D1234),
然后将它的左右两边的子字符串各自逆置(CBA 4321D),
然后将逆置后的结果(D1234ABC)再进行整体逆置, 这个结果就是
将原字符串左移3位后的结果。
其实就是将前后两部分各自逆置了两次,然而却把前面的一部分旋转到了这个字符串的尾部。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>void swap(char *start, char *end)//交换两个字符{ *start ^= *end; *end ^= *start; *start ^= *end;}void reverse(char *start, char *end){ assert(start); assert(end); while (start < end)//将字符串逆置 { swap(start,end); start++,end--; }}void str_shift(char *str,int len, int step){ char *middle = NULL; step %= len;//使得移位的步数小于字符串的长度 middle = str + step - 1;//middle将字符串分为两部分 assert(str); assert(len > 1); assert(step > 0); reverse(str,middle);//将分开的左半部分逆置 reverse(middle +1, str + len - 1);//将分开的右半部分逆置 reverse(str,str + len -1);//将整体逆置}int main(){ char msg[] = "ABCD1234"; int k = 0; printf("Please Enter:>"); scanf("%d",&k); printf("before : %s\n",msg); str_shift(msg,strlen(msg), k); printf("shift_after : %s\n",msg); system("pause"); return 0;}
第三种方法:
思路:使用双重字符串(例如:ABCDABCD),如果需要左旋1位,
则让字符串的首地址加上1,从此处截取字符串长度的字符(BCDA),
则这个结果就是左旋一位后的结果,但是这种方法不适合长度特别大的
字符串。
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>//------双重字符串//1234------1 2341234---左旋一位----(str+1,str+len-1) //左旋2位-----(str +2,str+ 2 +len -1) // 左旋step位----(str + k,str + step -1)void str_shift(char *str,int len, int step){ char *newstr = NULL; assert(str); assert(len > 1);//检查len是否大于1 assert(step > 0 );//检查要左旋的位数是否大于0 step %= len; newstr = (char *)malloc(sizeof(char) * len * 2 +1);//开辟双重字符串的空间 strcpy(newstr,str);//将原字符串拷贝到新的字符串中 strcat(newstr,str);//将原字符串连接到新字符串中,使之产生双重字符串 strncpy(str,newstr + step,len);//从左旋的位数开始,复制字符串长度个字符 free(newstr);//在堆上开辟的空间需要自行释放 newstr = NULL;}int main(){ char msg[] = "ABCD1234"; int k = 0; printf("Please Enter:>"); scanf("%d",&k); printf("before : %s\n",msg); str_shift(msg,strlen(msg), k); printf("shift_after : %s\n",msg); system("pause"); return 0;}
2.判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
AABCD右旋两个字符得到CDAAB
分析:可以在第一道题的思路上向下延伸:
要使得一个字符串是另一个字符串旋转之后得到的字符串,首先
两个字符串长度必须一样长,不然一定不会是旋转之后得到的字符串,
如果一个字符串是另一个字符串经过旋转可以得到的,那么这个字符串
一定是它双重字符串的一个字串。
例如:(ABCD)与(CDAB)——双重字符串(AB**CDAB**CD),
由此可以看出它是它的双重字符串的一个子串。
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>int is_sub_str(char *str,char *arr){ char *newstr = NULL; int len = strlen(str); assert(str); assert(arr); assert(len > 0);//检查len是否大于0 if (strlen(str) == strlen(arr)) { newstr = (char *)malloc(sizeof(char) * len * 2 +1);//开辟双重字符串的空间 strcpy(newstr,str);//将原字符串拷贝到新的字符串中 strcat(newstr,str);//将原字符串连接到新字符串中,使之产生双重字符串 if (strstr(newstr,arr) == NULL)//如果在双重字符串中没有找到arr这个字符串 { //则返回0 return 0; } return 1;//如果在双重字符串中找到了arr字符串,则返回1 free(newstr);//在堆上开辟的空间需要自行释放 newstr = NULL; } return 0;}int main(){ char msg[] = "ABCD1234"; char str[] = "CD1234AB"; printf("is sub str : %d",is_sub_str(msg,str));//是---返回1 不是----返回0 system("pause"); return 0;}
- 字符串的左旋问题解析
- 字符串的左旋问题解析
- 左旋字符串的做法
- 字符串的左旋右旋
- 字符串循环左移的问题
- 左旋字符串问题(有点料)
- 字符串左旋转问题
- 左旋字符串的应用 百度面试
- 左旋字符串的三种实现
- 字符串的左旋和右旋
- 左旋字符串的三种算法
- 字符串的左旋转
- 字符串的左旋转
- 字符串的左旋转
- 字符串的左旋转
- 一.字符串左旋转问题
- 字符串左移包含问题
- 字符串循环左移问题
- [BZOJ2086][Poi2010]Blocks(单调栈)
- 内部类和匿名内部类
- 最近最近~~
- 【c++】c++基础知识
- [BZOJ2016][Usaco2010]Chocolate Eating(二分)
- 字符串的左旋问题解析
- Python初接触--语句
- Java中如何遍历Map对象的4种方法
- C++笔记——c++编程思想(上)第四五六章数据抽象、初始化与清除
- 进驻csdn
- Shaders for Game Programmers and Artists(1) - First Shaders
- 初识gcc编译器
- [BZOJ3401][Usaco2009 Mar]Look Up 仰望(单调栈)
- Ivy简介