关于栈帧的两道题型

//1.实现一个函数,可以左旋字符串中的k个字符。
//ABCD左旋一个字符得到BCDA。
//ABCD左旋两个字符得到CDAB。
//分析:将ABCD左移4个字符得到ABCD,所以左移周期为4,所以有效的左旋次数为:count%strlen(str)
//代码1:常规方法,让A保持不动,BCD移位,得到BCDA;调用BCDA,让B保持不动,CDA移位,得到CDAB;···
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#pragma warning(disable:4996)
static leftMoveCore(char *str, int len)
{
	char tmp = str[0];//将第一个保存起来
	int i = 0;
	for (; i<len - 1; i++)
	{
		str[i] = str[i + 1];
	}
	str[i] = tmp;
}
void leftMove(char *str, int len, int count)
{
	assert(str);
	assert(len > 0);
	assert(count > 0);
	count %= len;
	while (count--)
	{
		leftMoveCore(str, len);
	}
}

int main()
{
	int count = 0;
	printf("Please Enter:");
	scanf("%d", &count);
	char str[] = "abcd1234";
	printf("before move:%s\n", str);
	leftMove(str, sizeof(str) / sizeof(str[0]) - 1, count);
	printf("after move:%s\n", str);
	system("pause");
	return 0;

}
//代码2  按左旋次数将字符串分为两部分,并对其分别进行局部逆置,最后全体逆置。
//abcd1234 左移3个字符
//abc d1234   (0  str+count-1)
//cba 4321d   (str+count  str+len-1)
//d1234abc
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#pragma warning(disable:4996)
static void reverseStr(char *start, char *end)
{
	assert(start);
	assert(end);
	while (start < end)
	{
		*start ^= *end;
		*end ^= *start;
		*start ^= *end;
		start++, end--;
	}
}
void leftMove(char *str, int len, int count)
{
	count %= len;
	reverseStr(str, str + count - 1);//字符串的局部逆置
	reverseStr(str + count, str + len - 1);//字符串的局部逆置
	reverseStr(str, str + len - 1);//字符串的整体逆置
}
int main()
{
	int count = 0;
	printf("Please Enter:");
	scanf("%d", &count);
	char str[] = "abcd1234";
	printf("before move:%s\n", str);
	leftMove(str, sizeof(str)/sizeof(str[0])-1, count);
	printf("after move:%s\n", str);
	system("pause");
	return 0;
}
//代码3  将字符串拼接到自身后,左旋n位,从n+1位开始往后读取字符串的总数位,即可得到目标字符串。
//abcd1234->abcd1234abcd1234
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#pragma warning(disable:4996)
void leftMove(char *str, int len, int count)
{
	count %= len;
	int newSize = 2 * len + 1;//+1是为了给\0开辟空间
	char *mem = (char *)malloc(sizeof(char)*newSize);//分配内存
	strcpy(mem, str);
	strcat(mem, str);
	strncpy(str, mem + count, len);
	free(mem);
}
int main()
{
	int count = 0;
	printf("Please Enter:");
	scanf("%d", &count);
	char str[] = "abcd1234";
	printf("before move:%s\n", str);
	leftMove(str, sizeof(str)/sizeof(str[0])-1, count);
	printf("after move:%s\n", str);
	system("pause");
	return 0;
}

//2.判断一个字符串是否为另一个字符串旋转之后的字符串。
//例:给定s1=AABCD和s2=BCDAA,返回1;给定s1=abcd和s2=ABCD,返回-1.
//分析:
//法一:一个字符串不动,将另一个字符串旋转一次与其比较一次,依次循环,若此过程中比较相等,则返回1;否则,返回-1.
//法二:将某一字符串自身拼接到自己后面,再利用strstr()在自身中找所需的字符串。
//str="abcd1234"
//substr="4abcd123"
#include <stdio.h>
#include <windows.h>
#include <assert.h>
int findLeftMove(char* str, char* substr)
{
	assert(str);
	assert(substr);
	int strLen = strlen(str);
	int subStrLen = strlen(substr);
	if (strLen != subStrLen)
	{
		return -1;
	}
	int newSize = 2 * strLen + 1;
	char* mem = (char *)malloc(sizeof(char)*newSize);
	strcpy(mem, str);
	strcat(mem, str);
	if (strstr(mem, substr))//在men字符串中查找substr字符串
	{
		return 1;
	}
	free(mem);
	return -1;
}
int main()
{
	int ret = findLeftMove("1234abcd", "4abcd123");
	printf(" ret:%d\n", ret);
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/bit666888/article/details/78487426
今日推荐