左旋字符串的三种方法,并判断一个字符串是否为另外一个字符串旋转之后的字符串。(strcpy,strncat,strcmp,strstr函数的介绍)

本文介绍了三种方法实现字符串左旋操作,包括直接旋转法、使用库函数(strcpy和strncat)的方法以及三段旋转法,并提供了判断字符串是否为旋转后结果的函数,使用了strcmp和strstr库函数进行比较。
摘要由CSDN通过智能技术生成

一.   实现一个函数,可以左旋字符串中的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("不是旋转后的结果");
	}
	
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值