1.实现一个函数,可以左旋字符串中的k个字符。
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
看到问题后的第一反应是左旋一个字符,那就是说把A放到字符串末尾,BCD依次向前移动一个位置,即得到BCDA。即先定义一个临时变量把A保存起来,BCD再依次移动,最后把A再写入。
void revolve_string(char *str, int k)
{
if (k > 0 && k < strlen(str)){
while (k){
char *p = str;
char tmp = *p;
while (*(p + 1)){ //依次前移
*p = *(p + 1);
p++;
}
*p = tmp;
k--;
}
}
}
但转念一想,如果我们把A和BCD整体逆置的话,这里把BCD当作一个整体,也可以得到结果。
如果是左旋俩位,我们把AB和CD分别看作整体,然后逆置,得到CDAB,再分别把C和D,A和B逆置,即可得到DCBA.
这里我们需要一个实现逆置的函数,之前的博客中写到过:
void adverse(char *left, char *right)
{
assert(*left);
assert(*right);
char tmp = 0;
while (left < right){
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
实现了逆置功能之后,我们要写一个旋转字符串的函数。我们先定义一个指针,找到他要旋转的第k个字符,然后标记,先进行内部逆置,再整体逆置。
void left_revolve(char *arr, int k,int len)
{
char *p = arr;
while (k>0){ //找到k之后的字符
p=arr+1;
k--;
}
adverse(arr, p);//A和B 逆置:BACD
adverse(p + 1, arr + len - 1);//C和D逆置:BADC
adverse(arr, arr + len - 1);//整体逆置:CDAB
}
完整程序为:
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#pragma warning(disable:4996)
void adverse(char *left, char *right)
{
assert(*left);
assert(*right);
char tmp = 0;
while (left < right){
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void left_revolve(char *arr, int k,int len)
{
char *p = arr;
while (k>0){
p=arr+1;
k--;
}
/*int i = 0;
while (i < k){
p = arr + i;
i++;
}*/
adverse(arr, p);//bacd
adverse(p + 1, arr + len - 1);//badc
adverse(arr, arr + len - 1);//cdab
}
int main()
{
char a[] = "ABCD";
int len = sizeof(a) / sizeof(a[0])-1;
int k = 0;
printf("左移几个字符?");
scanf("%d", &k);
left_revolve(a, k ,len);
printf("%s\n", a);
system("pause");
return 0;
}
2…判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
我们可以用刚刚的旋转字符串的方法,例如求CDAB是不是ABCD旋转之后的字符串,将字符串ABCD左旋俩个字符,再和CDAB比较。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
void reverse(char *left,char *right)
{
assert(*left);
assert(*right);
while (left < right){
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void revolve_string(char *str, int k)
{
//防御性检查
assert(str != NULL&&k < strlen(str));
int len = strlen(str);
reverse(str, str + k - 1);
reverse(str + k, str + len - 1);
reverse(str, str + len - 1);
}
int judge_string(char *str1, char *str2,int len)
{
int len1 = sizeof(str1);
int len2 = sizeof(str2);
if (len1 != len2){
return 0;
}
while (len1){
revolve_string(str1, 1,len);
if (strcmp(str1, str2) == 0){
return 1;
}
len1--;
}
return 0;
}
int main()
{
char a[] = "ABCD";
char b[] = "CDAB";
int len = sizeof(a) / sizeof(a[0]) - 1;
revolve_string(a, 2,len);
int ret = judge_string(a, b,len);
printf("%d\n", ret);
system("pause");
return 0;
}
但是如果是用户要判断,你不知道他要判断的字符串,也不知道参照串,那以上的方法是肯定不可行的。
方法一:
那我们就让源串一直旋转,判断是否与目标串相等,直至完整旋转过strlen(str)。
代码:
void reverse(char *left, char *right)
{
while (left < right){
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
void revolve_string(char *str, int k)
{
//防御性检查
assert(str != NULL&&k < strlen(str));//debug
/*if (str == NULL || k>strlrn(str)){
return;
}*/
int len = strlen(str);
reverse(str, str + k - 1);
reverse(str + k, str + len - 1);
reverse(str, str + len - 1);
}
int is_revolve_string(char *str1, const char *str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
assert(str1 != NULL&&str2 != NULL && (len1 == len2));
int i = 0;
for (i = 0; i < len1; i++){
revolve_string(str1, 1);
if (strcmp(str1, str2) == 0){
return 1;
}
}
return 0;
}
所以在这里我们就需要利用字符串操作了,首先我们用strncat把str拼接起来,再用strsrt求字串,就可以判断了。
例:初始串:ABBCD
strncat拼接之后:ABBCDABBCD
如果用户要判断的的串是初始串旋转之后的,那它一定是拼接之后的字串。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma warning(disable:4996)
#define N 20
void Merge_string(char *str)
{
str = strncat(str, str, strlen(str));
}
int Judge_string(char *str1, char *str2)
{
Merge_string(str1);
if (strstr(str1, str2) != NULL)
return 1;
else
return 0;
}
int main()
{
char arr1[N];
char arr2[N];
printf("请输入初始字符串:");
scanf("%s", &arr1);
printf("请输入要查找的左旋之后的字符串:");
scanf("%s", &arr2);
int res = Judge_string(arr1, arr2);
if (res == 1){
printf("是!\n");
}
else{
printf("不是!\n");
}
printf("%d", res);
system("pause");
return 0;
}
运行结果:
更多推荐
字符串的旋转问题
发布评论