一. 实现一个函数,可以左旋字符串中的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;}}//循环结束,字符串不相等,返回0return 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("不是旋转后的结果");}}