一. 实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
通过分析,可以知道实际的旋转次数,其实是k%(字符串长度)。假设一个字符串长度是3,那左旋4个字符后得到的字符串就是它本身。
1.直接旋转法
将字符串中的字符一个一个旋转
步骤:先定义一个变量tmp,将第一个字符赋值给这个变量,然后将后面的字符依次往前赋值,再将tmp的值赋值给最后一个字符
代码
#include<stdio.h>
#include<string.h>
//方法一
void Turnleft(char arr[6],int len,int k)
{
int time = k % len;//实际旋转次数
for (int i = 0; i < time; i++)
{
char tmp = arr[0];
for (int j = 0; j < len-1; j++)
{
//交换
arr[j] = arr[j + 1];
}
arr[len - 1] = tmp;
}
}
int main()
{
char arr[] = "ABCDEF";
int len = strlen(arr);
int k = 2;//旋转次数
Turnleft(arr, len, k);
printf("%s", arr);
}
2.库函数法
介绍使用到的库函数:
1).strcpy(); 字符串拷贝
2).strncat(); 字符串拼接 ->n个
这两个函数传递的参数都是地址,即指针
1).strcpy函数:
char * strcpy ( char * destination, const char * source );
destination目的地,即要追加的目标字符串,source指复制的内容
将源指向的 C 字符串复制到目标指向的数组中,包括终止 null 字符(并在该点停止)
举例说明:
注意,该函数复制的字符串会覆盖原字符串
2).strncat
char * strncat ( char * destination, const char * source, size_t num );
destination目的地,即要追加的目标字符串,source指追加的内容,num指追加字符的个数
将源的前 num 个字符附加到目标,以及终止 null 字符。
如果 source 中 C 字符串的长度小于 num,则仅复制直到终止 null 字符的内容
举例说明:
假设左旋"ABCDEF"这个字符串的两个字符,那么只需先复制后四个字符,然后再讲前两个字符拼接上去就行了
代码:
#include<stdio.h>
#include<string.h>
void Turnleft2(char arr[],int len,int k)
{
int time = k % len;//实际旋转次数
char tmp[100] = "0";
strcpy(tmp, arr + time);//复制字符串,这里的arr是数组首元素的地址
//arr + time 是数组第time+1个元素的地址
strncat(tmp, arr, time);//拼接,time表示拼接的字符串个数
strcpy(arr, tmp);//再把得到的新的字符串返回原数组
}
int main()
{
char arr[] = "ABCDEF";
int len = strlen(arr);
int k = 2;//旋转次数
Turnleft2(arr, len, k);
printf("%s", arr);
}
3.三段旋转法
代码:
#include<stdio.h>
#include<string.h>
//三段旋转法
void ReverseRange(char* arr,int start,int end)//数组名是数组首元素的地址
{
int left = start;
int right = end;
while (left < right)
{
char tmp = *(arr + left);//arr[left] = *(arr+left)
*(arr + left) = *(arr + right);
*(arr + right) = tmp;
left++;
right--;
}
}
void Turnleft3(char* arr,int len,int k)
{
int time = k % len;
//三段旋转
ReverseRange(arr, 0, time-1);
ReverseRange( arr, time ,len-1 );
ReverseRange( arr,0,len-1);
}
int main()
{
char arr[] = "ABCDEF";
int len = strlen(arr);
int k = 2;//旋转次数
Turnleft3(arr, len, k);
printf("%s", arr);
}
二.写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
解决这个题目,很重要的一个步骤就是如何判断两个字符串是否相同,我们可以通过每个字符的ASCII码值来比较
strcmp函数
strcmp(cmp是compare的缩写)用来比较字符串的大小
比较的内容:ASCII码值
比较规则:一个一个字符去比较,先出现的不一样的字符的大小,就是整个字符串的大小
(例如,zbc>abcdef,abcdef>abc)
输出整数表示>(大于)
输出0,表示=(等于)
输出负数,表示<(小于)
1.旋转后再判断
直接用上面写过的函数进行旋转,然后比较字符串的大小
注:这里旋转函数的旋转次数,就是字符串长度-1
代码:
#include<stdio.h>
#include<string.h>
//方法一
int Find_Turnleft(char arr1[6],char arr2[], int len)
{
for (int i = 0; i < len; i++)
{
char tmp = arr1[0];
for (int j = 0; j < len - 1; j++)
{
//交换
arr1[j] = arr1[j + 1];
}
arr1[len - 1] = tmp;
if (strcmp(arr1,arr2)==0)
{
return 1;
}
}
//循环结束,字符串不相等,返回0
return 0;
}
int main()
{
char arr1[] = "ABCDEF";
char arr2[] = "CDEFAB";
int len = strlen(arr1);
int ret = Find_Turnleft(arr1, arr2, len);
if (ret == 1)
{
printf("是旋转后的结果");
}
else
{
printf("不是旋转后的结果");
}
}
2.库函数法
将一段字符串拼接两次,那么它旋转后的结果一定能在这里面找到
介绍使用到的库函数
1).strstr函数
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
str1要扫描的 C 字符串。
str2包含要匹配的字符序列的 C 字符串。
返回指向 str1 中 str2 第一次出现的指针,如果 str2 不是 str1 的一部分,则返回 null 指针。
匹配过程不包括终止 null 字符,但到此为止。
举例介绍:
代码:
#include<stdio.h>
#include<string.h>
//库函数法
int Find_Turnleft2(char arr1[6], char arr2[], int len)
{
char tmp[100] = "0";
strcpy(tmp, arr1);
strncat(tmp, arr1, len);
return strstr(tmp, arr2) != NULL;
//表达式为假返回0,为真返回1
}
int main()
{
char arr1[] = "ABCDEF";
char arr2[] = "CDEFAB";
int len = strlen(arr1);
int ret = Find_Turnleft(arr1, arr2, len);
if (ret == 1)
{
printf("是旋转后的结果");
}
else
{
printf("不是旋转后的结果");
}
}