目录
题目名称:
字符串左旋
题目内容:
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
题目解题分析:
解法1:常规解法
思路分析:第一种方法的解题思路是可以将左旋分为两个步骤。第一个步骤是确定左旋的次数。第二个步骤是对字符串左旋一个字符进行内部操作,创建一个临时变量,将字符串首元素存储起来,将其余字符依次向左移动一位,最后首元素放进最后一个位置即可。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
void Leftfound(char* p, int k)
{
int len = strlen(p);
int time = k % len;//左旋次数
int i = 0, j = 0;
for (i = 0; i < time; i++)//控制左旋次数
{
char tmp = p[0];
for (j = 0; j <len-1; j++)//进行左旋一次的内部操作
{
p[j] = p[j + 1];
}
p[j] = tmp;
}
}
int main()
{
char str[] = "abcde";
int n = 0;
scanf("%d", &n);
Leftfound(str,n);
printf("%s", str);
return 0;
}
解法2:拼接法
思路分析:假设将字符串abcde左旋2次,重新创建一个数组tmp,使用strcpy函数将cde拷贝进tmp,在使用strncmp函数将前两个字符拷贝进tmp中,最后将tmp拷贝回字符串中。
#include<stdio.h>
#include<string.h>
void Leftfound(char* p, int k)
{
int len = strlen(p);
int time = k % len;
char tmp[100] = { 0 };
strcpy(tmp, p + time);
strncat(tmp, p, time);
strcpy(p, tmp);
}
int main()
{
char str[] = "abcde";
int n = 0;
scanf("%d", &n);//左旋次数
Leftfound(str, n);
printf("%s", str);
return 0;
}
解法3:三段逆序法
思路分析:假设将字符串abcde左旋k个字符,第一步将前面k个字符逆序,第二部将剩下的字符逆序,最后将前两次逆序的结果整体逆序,这样就完成字符串左旋。
#include<stdio.h>
#include<string.h>
void Reverse_part(char* p, int start,int end )
{
int left = start;
int right = end;
while (left < right)
{
char tmp = p[left];
p[left] = p[right];
p[right] = tmp;
left++;
right--;
}
}
void Leftfound(char* p, int k)
{
int len = strlen(p);
int time = k % len;
Reverse_part(p, 0,time-1);
Reverse_part(p, time, len-1);
Reverse_part(p, 0, len-1);
}
int main()
{
char str[] = "abcde";
int n = 0;
scanf("%d", &n);//左旋次数
Leftfound(str, n);
printf("%s", str);
return 0;
}
字符串旋转结果:
写一个函数,判断一个一个字符串旋转之后的字符串是否为另外字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
方法1:
分析思路:按照前面介绍的第一种方法,将字符串左旋一个字符就判断是否与另一个字符串相等若相等,则返回1,若不相等,就继续左旋,直到结束都不相等,返回0。
#include<stdio.h> #include<string.h> int if_left(char* p1,char *p2) { int len = strlen(p1); int i = 0, j = 0; for (i = 0; i < len; i++)//控制左旋次数 { char tmp = p1[0]; for (j = 0; j <len-1; j++)//进行左旋一次的内部操作 { p1[j] = p1[j + 1]; } p1[j] = tmp; if (strcmp(p1, p2) == 0) { return 1; } } return 0; } int main() { char s1[] = "abcde"; char s2[10] = { 0 }; scanf("%s", s2); int n = if_left(s1,s2); if (n == 1) { printf("yes!\n"); } else { printf("no!\n"); } return 0; }
方法2:
假设s1字符串为abcde,使用strcat函数在字符串后再追加该字符串,s1字符串就变为了abcdeabcde,s1的所有子字符串就包含了abcde所有左旋之后可能的结果,再使用strstr函数看能不能再abcdeabcde中找到s2,若能找到则返回1,否则返回0.
#include<stdio.h> #include<string.h> int if_left(char* p1, char* p2) { strcat(p1, p1); char *p = strstr(p1, p2);//strstr函数返回字符串s2在s1中第一次出现的位置,若找不到则返回NULL if (p == NULL) { return 0; } return 1; } int main() { char s1[100] = "abcde"; char s2[100] = { 0 }; scanf("%s", s2); int n = if_left(s1, s2); if (n == 1) { printf("yes!\n"); } else { printf("no!\n"); } return 0; }