牛课网编程~~倒置字符串

前言

一道牛客网的编程题。。。
题目地址

解法1思路解析

拿到题目之后,我的思考首先是使用原空间进行倒置还是新开辟一个数组去存放倒置的结果。
这里我选择了新开辟一个空间。
因为倒置到新的数组中的时候,I like Beijing.会变成 Beijing. like I
所以在旧数组中的操作,我们选择从数组最后端开始操作
在这里插入图片描述
上述过程在放置完Beijing.之后,p要向前寻找到like,然后是I,这是个循环的过程
因为当p指向了I的时候,前面的元素不是’ ',我们无法预料,那么这个情况单独考虑,这样循环的条件就是当p!=str
代码部分实现:

	while (p != str)
	{
    
    
		char* t = p - 1;
		if (*t == ' ')
		{
    
    
			while ((*p) != '\0' && (*p) != ' ')
			{
    
    
				*q++ = *p++;//q是指向新数组的指针
			}
			p = t + 1;
			*(q) = ' ';
			q++;
		}
		p--;
	}

当p==str的情况下,依旧是赋值到新的数组中

	while ((*str) != ' ')
	{
    
    
		*q++ = *str++;
	}
	*q = '\0';
	//注意当查找到str的时候,在新数组中,相当于到了结束的时候,所以在结尾加上\0,表示结束标志

解法1完整代码

void ReserveString(char* str)
{
    
    
	int i = 0;
	int len = strlen(str);
	char b[100] = {
    
     0 };
	char* q = b;
	char* p = str+len-1;
	while (p != str)
	{
    
    
		char* t = p - 1;
		if (*t == ' ')
		{
    
    
			while ((*p) != '\0' && (*p) != ' ')
			{
    
    
				*q++ = *p++;
			}
			p = t + 1;
			*(q) = ' ';
			q++;
		}
		p--;
	}

	while ((*str) != ' ')
	{
    
    
		*q++ = *str++;
	}
	*q = '\0';
	printf("%s", b);
}
int main()
{
    
    
	char str[100] = {
    
    0};	
	gets_s(str);
	ReserveString(str);
	return 0;
}

解法2思路解析

前面说到,在看到这个题目的时候,我的第一做法是开辟新的空间,进行倒置的存储,其实正常情况下,如果可以使用原空间,那么一定是最好的,毕竟我们要考虑时间复杂和空间复杂。倘若我们要倒置的字符串很长,新开辟空间会耗费资源的。
接下来的写法就是使用原空间的做法
首先:将这个字符串中的每一个单词逆序
然后:将整个字符串逆序一次
图解:
在这里插入图片描述
实现逆序操作的代码想必大家已经熟的不能再熟了
使用两个指针指向字符串前后两个位置,然后进行前后逆序
代码如下:

void resverse(char* left, char* right)
{
    
    
	assert(left && right);//避免left,right为空指针
	while (left < right)
	{
    
    
		char t = *left;
		*left = *right;
		*right = t;
		left++;
		right--;
	}
}

逆序三个单词的代码:

//start和end代表一个单词首尾指针
while (*end != '\0')//条件是不遇到\0,不然之间还是有单词的
	{
    
    
		while (*end != ' ' && *end!='\0')
		{
    
    
			end++;
		}
		//逆序这两个指针之间的内容,相当于逆序单词
		//注意end-1,因为此刻是end=' '了,单词是在' '前面的 
		resverse(start, end - 1);
		
		//指向下一个单词
		//如果到了最后一个\0,start就不能往后走了
		if (*end == '\0')
		{
    
    			
			start = end;
		}
		//如果没有遇到就是正常的指向下一个单词
		else
		{
    
    
			start = end + 1;
		}
		end = start;
	}

逆序整个单词的代码:

	resverse(a, a + strlen(a) - 1);

解法2完整代码

#include<stdio.h>
#include<string.h>
#include<assert.h>
void resverse(char* left, char* right)
{
    
    
	assert(left && right);//避免left,right为空指针
	while (left < right)
	{
    
    
		char t = *left;
		*left = *right;
		*right = t;
		left++;
		right--;
	}
}
int main()
{
    
    
	char a[100] = {
    
     0 };
	gets_s(a);
	char* start = a;
	char* end = start;
	while (*end != '\0')//条件是不遇到\0,不然之间还是有单词的
	{
    
    
		while (*end != ' ' && *end!='\0')
		{
    
    
			end++;
		}
		//逆序这两个指针之间的内容,相当于逆序单词
		resverse(start, end - 1);
		//指向了下一个单词
		if (*end == '\0')
		{
    
    
			//如果到了最后一个\0,start就不能往后走了
			start = end;
		}
		else
		{
    
    
			start = end + 1;
		}
		end = start;
	}

	//接下来整个串再逆序一下
	resverse(a, a + strlen(a) - 1);
	printf("%s", a);
	return 0;
}

最后的总结

当时写题目的时候是有时间限制的,我没有在规定的时间内完成代码,可以给大佬们看看我的代码

#include<stdio.h>
#include<string.h>
void ReserveString(char* str)
{
    
    
	int i = 0;
	int len = strlen(str);
	char b[100] = {
    
     0 };
	char* q = b;
	char* p = str+len-1;
	while (p != str)
	{
    
    
		char* t = p - 1;
		if (*t == ' ')
		{
    
    
			while ((*p) != '\0' && (*p) != ' ')
			{
    
    
				*q++ = *p++;
			}
			p = t + 1;
			*(q) = ' ';
			q++;
		}
		p--;
	}

	while ((*str) != ' ')
	{
    
    
		*q++ = *str++;
	}
	*q = '\0';
	str = b;
}
int main()
{
    
    
	char str[100] = {
    
    0};	
	gets_s(str);
	ReserveString(str);
	printf("%s", str);
	return 0;
}

就是题解一的过程,不同的是当时在考虑的时候,想着指针是传递地址的,所以在倒置函数内部,我把新数组的空间赋给了str,然后返回到main函数中str找到b的首地址,完美的把后面的内容打印出来,当时以为是这么回事,后来截至时间过了之后调试了一把。。。。
函数结束后,函数内部的空间会被自动释放,b那个空间是个什么啊,还赋值给str了。。。。
在这里插入图片描述
各位大佬观看时如果发现错误,务必要及时指正我啊!

ps:说说最近,开通博客呢是想记录自己重学C语言的历程,但是距离上次博客已经是多久以前了,其实我花在C上的时间远远少于当时心中所想。所以说我在干什么呢。。。对接口。。感觉在写shi,循环里面发请求加异步还传多组参数。c,我究竟是什么丧心病狂。
然后又到了考试周,明天还有数据结构摸底测,希望快点放假,寒假我要好好学习!

猜你喜欢

转载自blog.csdn.net/m0_50546235/article/details/121593164