字符串翻转和旋转问题和例题


/1.
//有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
// 要求:
// 不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)。

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
int Mystrlen(const char *src)
{
	int len = 0;
	assert(src !=NULL);
	while (*src++ != '\0')
	{
		len++;
	}
	return len;
}
void reverse_str(char *p1, char *p2)   //翻转函数。
{
	char ch = 0;
	assert(p1 != NULL && p2 != NULL);
	while (p1 < p2)
	{
		ch = *p1;
		*p1 = *p2;
		*p2 = ch;
		p1++;
		p2--;
	}
}
void Myreverse(char * array)
{
	int len = 0;
	char *start = NULL;
	char *end = NULL;
	assert(array !=NULL);
	len = Mystrlen(array);
	reverse_str(array, array+len-1);  //翻转整个字符串。接下来要做的就是翻转每个单词了。
	//printf("array = %s\n",array);
	while (*array != '\0')    //这个循环就是翻转每个单词了。
	{
		start = array;
		while ((*array != ' ') && (*array != '\0'))
		{
			array++;                 //arrray指向了空格或者是'\0'
		}
		end = array - 1; 
		reverse_str(start, end);
		if (*array != '\0')   //这里容易出错。记得要加上这个条件。
		{
			array++;    //当它指向空格时,前进一步指向新的单词的起始位置。但是如果到字符串的尾部的话,array再加加,将使它跳过\0,导致最外层的循环不会结束。
		}
	}
}
int main()
{
	char array[100] = "student a am i";
	//myreverse(array);
	Myreverse(array);
	printf("array = %s\n",array);
	printf("hello...\n");
	system("pause");
	return 0;
}


//2.实现一个函数,可以左旋字符串中的k个字符。
// AABCD左旋一个字符得到ABCDA
// AABCD左旋两个字符得到BCDAA

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
//方法一:
void reverse_ch(char * str, int n)
{
	int i = 0;
	char *p = NULL;
	char *p1 = NULL;
	assert(str != NULL);
	p = str;
	p1 = str + strlen(str);
	n = n % 5;   //这样一条语句,能让循环减少很多次,提高效率。因为旋转5次字符串变成原来的字符串了。
	for (i = 0; i < n; i++)    //将n个字符旋转到字符串的后面。
	{ 
		*p1++ = *p++;
	}
	*p1 = '\0';
	while ( (*(p-n) = *p++) != '\0')      //将整个字符串前移
	{
		;
	}
}


 //方法二        前n个字符翻转一次,字符串剩下的字符翻转一次,最后整个字符串翻转一次。这个方法简单,但是n一定要小于等于strlen(str).
void myreverse(char *left, char *right)
{
	char temp = 0;
	assert(left != NULL && right != NULL);
	while (left < right)
	{
		temp = *left;
		*left = *right;
		*right = temp;
		left++;
		right--;
	}
}
void reverse_ch3(char *str, int n)   //这个方法简单,但是n一定要小于等于strlen(str).
{
    assert(str != NULL);
	myreverse(str,str+n-1);
	myreverse(str+n,str+strlen(str)-1);
	myreverse(str,str+strlen(str)-1);
}
int main()
{
	char str[100] = "AABCD";
	/*reverse_ch(str, 20);
	printf("str = %s\n",str);*/
	reverse_ch3(str, 6);
	printf("str = %s\n",str);
	printf("hello...\n");
	system("pause");
	return 0;
}

//3.
// 判断一个字符串是否为另外一个字符串旋转之后的字符串。
// 例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0.
//
//
// AABCD左旋一个字符得到ABCDA
// AABCD左旋两个字符得到BCDAA
//
// AABCD右旋一个字符得到DAABC
// AABCD右旋两个字符得到CDAAB


#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
//方法一: 字符串旋转一次判断一下。
void reverse_ch1(char * str, int n)
{
	int i = 0;
	char *p = NULL;
	char *p1 = NULL;
	assert(str != NULL);
	p = str;
	p1 = str + strlen(str);
	for (i = 0; i < n; i++)    //将n个字符旋转到字符串的后面。
	{ 
		*p1++ = *p++;
	}
	*p1 = '\0';
	while ( (*(p-n) = *p++) != '\0')      //将整个字符串前移
	{
		;
	}
}
int is_revstr(char *str1, char *str2)  //str1源字符串,str2是判断字符串
{
	int len1 = 0;
	int len2 = 0;
	assert(str1 != NULL && str2 != NULL);
	len1 = strlen(str1);
	len2 = strlen(str2);
	if (len1 != len2)
	{
		return 0;   //一个字符串不为另外一个字符串旋转之后的字符串。
	}
	else
	{
		while (len1 > 0)    //源字符串向左旋转len1-1次,看每次旋转后的结果是否为另个字符串。
		{
			if(strcmp(str1, str2) == 0)
			{
				return 1;
			}
			reverse_ch1(str1,1);
			len1--;
		}
	}
	return 0;
}


//方法二:  简单方法。将源字符串追加到源字符的后面,形成一个新的字符串,在看str2是否是这个新字符串的子串,如果是,则是翻转后的字符串。
int is_revstr2(char *str1, char *str2)
{
	int len1 = strlen(str1);
	int len2 = strlen(str2);
	assert(str1 != NULL && str2 != NULL);
	
	if (len1 != len2)
	{
		return 0;   //一个字符串不为另外一个字符串旋转之后的字符串。
	}
	strncat(str1,str1,strlen(str1));//将源字符串追加到源字符的后面,形成一个新的字符串,在看str2是否是这个新字符串的子串,如果是,则是翻转后的字符串。
	if (strstr(str1, str2) != NULL)  //strncat会自动加上\0,这里不能用strcat,用这个会崩溃。
	{
		return 1;
	}
	else
		return 0;
}
int main()
{
	int ret = 0;
	char array[100] = "AABCD";
	char array2[100] = "DAABC";
	//ret = is_revstr(array,array2);
	ret = is_revstr2(array,array2);
	if (ret == 1)
	{
		printf("两个字符串旋转后相同\n");
	}
	else
	{
		printf("两个字符串旋转后不同\n");
	}
	printf("hello...\n");
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值