用递归,栈帧结构,栈的先进后出思想方法解决左旋问题

本文介绍了如何通过递归和栈帧特性实现字符串的左旋操作,并提供了一个判断一个字符串是否为另一个字符串旋转后的函数。通过对栈帧特性的利用,文章展示了如何在递归过程中巧妙地修改变量值。


 1.实现一个函数,可以左旋字符串中的k个字符。 
ABCD左旋一个字符得到BCDA 
ABCD左旋两个字符得到CDAB 
(1)用递归方法,使得函数递归k次后打印第k次递归的字符串,然后再返回首地址依次打印出来
#include<stdio.h>
char *q = NULL;
int m = 0;
char* runLeft(char *p, int k);
int main()
{
	char *p = "ABCD";
	q = p;             //全局变量q保存字符串首地址
	int k = 1;
	m = k;              //全局变量m保存k值使得输出字符串后从头再输出m个字符变量
	runLeft(p, k);
	int i = 0;
	for (i = 0; i < m; i++)
	{
		printf("%c", *(q + i));
	}
	return 0;
}
char* runLeft(char *p, int k)
{
	if (k <= 0)           //每次递归k-1,递归k次
	{
		printf("%s", p);
	}
	else
	{
		   p= p+1;
		   k=k-1;
		 runLeft(p, k);
	}
	
}

(2)根据栈帧结构特性,先用字符串拷贝和连接使字符串变为原来的2倍然后通过依次改变函数调用的保存下一语句的地址内容循环输出4个字符(这里的4是字符串长度可以用sizeof()-1求出,用全局变量保存,这里直接默认用4)

#include<stdio.h>
#include<string.h>
char *str2 = NULL;
void Turnleft(char *str1, int k);
int main()
{
	char a[]= "abcd";
	int k = 2;
	char b[] = "abcdabcd";          //因为不会使用strcpy和字符串连接函数,给出头文件接把结果b数组内容给出
	str2 = (b + k);          //根据k值修改目标要修改的地址
	Turnleft(b);
	return 0;
}
void Turnleft(char *str1)
{
	                           
	char *q = &str1;                   //获得临时变量地址               
	*q = str2;                          //修改临时变量中的内容
	int i = 4;
	for (i = 0; i < 4; i++)            //循环输出字符
	{
		printf("%c",*(str1+i));
	}
}
2.判断一个字符串是否为另外一个字符串旋转之后的字符串。 
例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0. 


AABCD左旋一个字符得到ABCDA 
AABCD左旋两个字符得到BCDAA 

AABCD右旋一个字符得到DAABC 
根据栈的先进后出特性,建立一个数组,然后依次左移比较,如果在左移b的长度之前不匹配,表示不匹配,若有一次匹配,则退出函数返回1,
#include<stdio.h>
int Turnleft(char *a, char *b);
int main()
{
	char a[] = "aabcd";
	char b[] = "abcaa";
	int ret = Turnleft(a,b);
	if (ret)
	{
		printf("yes\n");
	}
	else
		printf("no\n");
	return 0;
}
int Turnleft(char a[6], char b[6])
{
	char arry[100];              //定义数组arry保存a数组的值与b进行比较
	memset(arry,'\0',100);
	int j = 0;
	for (j = 0; j < 5; j++)   // 将a数组的值送入arry,这里的5也可以由定义全局变量,再用sizeof()求出
	{
		arry[j] = a[j];    
	}
	char *str1 = b;
	char *str2 = arry;
	int i = 0;
	for (i = 0; i <= 5; i++)
	{
		if (Strcmp(str1, str2)==1)//定义了Strcmp函数比较arry与b,如果在左移过程中相同,就直接返回1
		{
			return 1;
		}
		else  
		{
			arry[5+i] = arry[i];
			str2=str2 + 1;
		}
	  }
	return 0;                //如果左移5次一直不匹配则返回0
}
int Strcmp(char *a, char *b)   //比较函数,其中数字5是b数组的元素个数,也可定义全局变量在main中求出
{
	int i = 0;
	for (i = 0; i <= 5; i++)
	{
		if ((*a) != (*b))
		{
			return 0;
		}
		a=a+1;
		b=b+1;
	}
	return 1;
}

经过上面两个题可以发现,栈帧的生成与返回过程都可以用来间接修改临时变量的值从而导致函数结果有所不同,其中要使用这种方法,深刻了解栈帧的生成与销毁过程非常重要。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值