C语言-写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串-多方法(前两个可为得到一个旋转字符串,并非判断)

题目大概:写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串

EG:

给定s1 = AABCD和s2 = BCDAA,返回1
给定s1 = abcd和s2 = ACBD,返回0

示范:
//AABCD左旋一个字符得到ABCDA
/
//AABCD左旋两个字符得到BCDAA
/
//AABCD右旋一个字符得到DAABC

一.法1(字符的重新排序)(简称:暴力搞定)

这个方法对题目所要求的有点变扭,不好在函数中直接return 0 或 1 ,不过可以在main函数内printf("%d\n",0);或printf("%d\n",1);而且本方法比较合适于输入一个数,得到所想的到的旋转结果,所以,兄弟们想要直接准确的解决本题,可以看除了法3的方法>>>☺❤<<<    因为我想有些初学者可能看到这题,会首先想到这个解法

(1)解题思路

 我们拿来一个字符数组arr来说明

char arr[ ]="ABCD";

通过图来理解吧

通过图示,我们便有了关键代码的走动方向:
小程序:因为是数组,用不着旋转的数(首元素之后的数)每个元素都向后走一位。即arr[i]被后一位arr[i+1]赋值(arr[i]=arr[i+1]),在这之前,先初始化一个字符变量(ret),使ret=arr[0](首元素,即要旋转的元素),那么,随着i++,就可以把首元素排放到最后一位。

我们便可以根据要旋转的次数来得到相应的结果(用while来循环小程序) 

下面,我们便可以写出这个项目了

(2)代码实现 
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<string.h>
// 定义一个函数,用于将字符串向左移动指定数量的字符
void left_move(char* p, int k) 
{
    assert(p != NULL); // 检查输入的字符串指针是否有效
    int len = strlen(p);
    // 遍历k次,每次将第一个字符移到末尾
    for (int i = 0; i < k; ++i)
    {
        char tmp = *p; // 存储首个字符

        for (int j = 0; j < len - 1; ++j)  
        {
            //len - 1 是为了防止*(p+1+j)越界. 
            *(p + j) = *(p + j + 1);
        }
        // 将临时变量tmp赋值给原字符串的末尾位置
        *(p + len - 1) = tmp;//len - 1就是最后一个元素的位置
    }
}
int print(char* a1, char* a2, int l1, int l2)
{
    int i = 0;
    if (l1!= l2)
    {
        return 0;
    }
    else
    {
        int count = 0;
        for (i = 0; i < l1; i++)
        {
            if (a1[i] == a2[i])
            {
                count++;//需要每位都相等才可返回1
            }
        }
        if (count < l1)
        {
            return 0;
        }
        else if (count == l1)
        {
            return 1;
        }
    }
}
int main()
{
    char arr1[20] = "AABCD";
    int n = 0;
    scanf("%d", &n);
    left_move(arr1, n);
    char arr2[20] = "ABCDA";
    int len1 = strlen(arr1);
    int len2 = strlen(arr2);
    int ret = print(arr1, arr2, len1, len2);
    printf("%d\n", ret);
	return 0;
}

运行结果: 

 在这个代码中,n只有输入1,才可以输出1,这是取决于arr2的,这就是这个代码面对本体的一个缺陷:

二.法2(三倒序输出) 

(1)解题思路 

从方法的字面意思,也就是我们可以通过三次不同的倒叙排序来的到左旋转n位后的旋转字符串

同样:

我们拿来一个字符数组arr来说明

char arr[ ]="ABCDE";

我们假设得到左旋转2位后的字符串,需要三次倒排序

说明:字符串长度:len

第一次:整体

ABCDE----->EDCBA

第二次:若左旋转2位,前(len-2)位

EDC  BA----->CDE  BA

第三次:后两位

CDE BA----->CDE AB

经过三次倒排序后:

CDEAB ----->这便是我们所想要的答案,还是很好理解的xdm!!!

下面,我们对思路实现化---代码

(2)代码实现
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
void fun(char* p, int len, int n)
{
//第一次
	int left = 0;
	int right = len - 1;
	while (left < right)
	{
		int tmp = 0;
		tmp = *(p + left);
		*(p + left) = *(p + right);
		*(p + right) = tmp;
		left++;
		right--;
	}
//第二次
	left = 0;
	right = len - 1 - n;
	while (left < right)
	{
		int tmp = 0;
		tmp = *(p + left);
		*(p + left) = *(p + right);
		*(p + right) = tmp;
		left++;
		right--;
	}
//第三次
	left = len - n;
	right = len - 1;
	while (left < right)
	{
		int tmp = 0;
		tmp = *(p + left);
		*(p + left) = *(p + right);
		*(p + right) = tmp;
		left++;
		right--;
	}
	int i = 0;
	for (i = 0; i < len; i++)
	{
		printf("%c", *(p++));
	}
}
int main()
{
	char arr[] = "ABCDEFG";
	int len = strlen(arr);
	int n = 0;
	scanf("%d", &n);
	fun(arr, len, n);
	return 0;
}

运行结果

根据这个方法,我们也可以将前两个字符拿出来,放到后面去,再对这两个 字符进行倒排序

代码如下

#include <stdio.h>
#include <string.h>
int main(void)
{
	char arr[20] = { "" };
	printf("请输入你要旋转的字符串:");
	gets(arr);
    int n = 0;
	printf("请输入你要旋转的字符数:");
	scanf("%d", &n);
	char b[20] = { "" };
	strcat(b, arr + n);
	strncat(b, arr, n);
	puts(b);
	return 0;
}

三.法3(叠加字符串判断法)

(1)解题思路 

我么根据图文来解释哈:

在这是char arr[]="ABCDE",以此在后面复制一份;

红色下标走,是可以包含了旋转后的所有旋转字符串

(2)代码实现 

 补充:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int fun(char* arr1, char* arr2)
{
	int len1 = strlen(arr1);
	int len2 = strlen(arr2);
	if (len1 != len2)
	{
		return 0;
	}
	strncat(arr1, arr1, len1);//用strncat来连接字符串
	char* ret = strstr(arr1, arr2);//用于判断,前有介绍
	if (ret == NULL)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
int main()
{
	char arr1[100] = "ABCD";
	char arr2[] = "CDAB";
	int a = fun(arr1, arr2);
	printf("%d\n", a);
	return 0;
}

运行结果

兄弟们,家人们,如果还有别的好法子,欢迎在评论区发表分享哦😘(我想学学😋)

今天就先到这了 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值