1.实现一个函数,可以左旋字符串中的k个字符,详细解释2.判断一个字符串是否为另外一个字符串旋转之后的字符串。

1.实现一个函数,可以左旋字符串中的k个字符。
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB

在这里插入图片描述

第一种解法,三步旋转法
就是将一个字符串通过旋转三次来的到所需要的结果。以一个列子来进行说明
有一个字符串:ABCDEFG,需要向左旋转3个字符
1.进行第一次旋转,将k个字符之前的字符进行旋转,得到的结果是:
DCBAEFG
2.第二次旋转,是要将k字符后剩余的字符进行旋转,得到的结果是:
DCBAGFE
3.第三次旋转是在前两次的基础上,进行整体旋转,得到的结果是:
EFGABCD
在这三次旋转的过程中可以看出这是一个重复的过程,我们只需要写一个用来旋转的函数,再传入相应的参数就能解决问题了。
最后就得到题目要求的结果了,具体程序如下:

#include<stdio.h>
#include<Windows.h>
void reverse(char *left, char *right)
{
	char tmp = 0;
	while (left < right)
	{
		tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
void Left_Reverse(char *arr, int len, int k)
{
	reverse(&arr[0], &arr[k - 1]);
	reverse(&arr[k], &arr[len - 1]);
	reverse(&arr[0], &arr[len - 1]);
}
int main()
{
	char arr[] = "ABCDEFG";
	int len = sizeof(arr) / sizeof(arr[0])-1;//(别忘了要减去‘\0’字符)
	Left_Reverse(arr,len,4);
	printf("%s", arr);
	system("pause");
	return 0;
}

第二种解法,循环交换法

这种解法的思路很简单,需要用到两个循环,第一个循环用来从第一个字符遍历到所要求的的k个字符,每遍历一个字符,我们将第一个字符保存到另一个变量中,让其原来所待的位置空出来,然后用第二个for循环将剩余的字符串都前进一个位置,最后空出最后一个位置,再将第一个位置的值填到最后一个位置,这样就左旋了一个字符。然后重复k次,就实现了程序。

(注意:每次放到另一个变量中保存的都是字符串的第一个字符,然后把这个字符赋值到最后一个字符所在的位置

#include<stdio.h>
#include<Windows.h>
void Left_Reverse(char *arr,int len, int k)
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	for (i = 0; i < k; i++)
	{
		tmp = arr[0];
		for (j = 0; j < len-1; j++)
		{
			arr[j] = arr[j + 1];
		}
		arr[len - 1] = tmp;
	}
}
int main()
{
	char arr[] = "ABCDEFG";
	int len = sizeof(arr) / sizeof(arr[0])-1;
	Left_Reverse(arr,len,4);
	printf("%s", arr);
	system("pause");
	return 0;
}

2.判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
————————————————————————————————————
第一种解法,续上一题的第一种解法,将原字符串的每一种旋转结果求出来与要求的字符串进行比较,有相同的则说明该字符是原字符串旋转得到的字符串。

#include<stdio.h>
#include<Windows.h>
#include<string.h>
void reverse(char *left, char *right)
{
	char tmp = 0;
	while (left < right)
	{
		tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
int Left_Reverse(char *arr,const char *_arr,int len)
{
	int i = 0;
	for (i = 1; i < len; i++)
	{
		reverse(&arr[1], &arr[len - 1]);
		reverse(&arr[0], &arr[len - 1]);
		printf("%s\n", arr);
		if (0 == strcmp(_arr, arr))
		{
			return 1;
		}
	}
	return 0;
}
int main()
{
	char arr[] = "ABCDEFG";
	const char _arr[] = "CDEFGAB";
	int len = sizeof(arr) / sizeof(arr[0])-1;
	int x = Left_Reverse(arr,_arr,len);
	if (x == 0)
	{
		printf("不是该字符串的旋转字符!");
	}
	else
	{
		printf("是该字符串的旋转字符!");
	}
	system("pause");
	return 0;
}

第二种解法,是上一个题第二种解法的延伸

#include<stdio.h>
#include<Windows.h>
#include<string.h>
int Left_Reverse(char *arr,const char *_arr,int len)
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	for (i = 0; i < len; i++)
	{
		tmp = arr[0];
		for (j = 0; j < len-1; j++)
		{
			arr[j] = arr[j + 1];
		}
		arr[len - 1] = tmp;
		if (0 == strcmp(_arr, arr))
		{
			return 1;
		}
	}
	return 0;
}
int main()
{
	char arr[] = "ABCDEFG";
	const char _arr[] = "CDEFGAB";
	int len = sizeof(arr) / sizeof(arr[0])-1;
	int x = Left_Reverse(arr,_arr,len);
	if (x == 0)
	{
		printf("不是该字符串的旋转字符!");
	}
	else
	{
		printf("是该字符串的旋转字符!");
	}
	system("pause");
	return 0;
}

第三种解法是效率最高的解法,不用向前两种一样需要多次遍历,主要思路是:
将原字符串copy后再拼接到其后面(如:ABCD -->ABCDABCD)
原字符串不管是向左还是向右旋转得到的字符串都会是它拼接后的字串,我们就只需判断其是否是字串。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include<string.h>
int Left_Reverse(char *arr,const char *_arr,int len)
{
	char arr_1[30] = { 0 };
	strcpy(arr_1, arr);
	strcat(arr_1, arr);
	if (strstr(arr_1, _arr) == NULL)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
int main()
{
	char arr[] = "ABCDEFG";
	const char _arr[] = "CDEFGAB";
	int len = sizeof(arr) / sizeof(arr[0])-1;
	int x = Left_Reverse(arr,_arr,len);
	if (x == 0)
	{
		printf("不是该字符串的旋转字符!\n");
	}
	else
	{
		printf("是该字符串的旋转字符!\n");
	}
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44930562/article/details/91057161