字符串逆序和单词逆置(I like beijing.)

代码在5_23中

一、字符串逆序

首先,先实现字符串的逆序。(其实这里有两种情况,第一个是不更改原先字符串内容,在屏幕上逆序打印;第二个是将原先字符串内容逆序,再正着打印。这两种在屏幕上显示的内容是一样的,但具体是哪一种要看题目要求)

(一)不更改原先字符串内容,在屏幕上逆序打印

先看一下代码是如何如何实现的:

#include <stdio.h>
#include <string.h>

int main()
{
	char arr[20] = { 0 };
	gets(arr);
	int len = strlen(arr);
	char* end = arr + len - 1;
	char* start = arr;
	while (start <= end)
	{
		printf("%c", *end);
		end--;
	}
	return 0;
}

 这里的思路是:先用一个char* 指针找到字符串中的最后一个字符,然后向前移动并打印,直到该指针移动到第一个字符时,停止打印。

注:这里输入一个字符串用的是 gets  函数,没有用 scanf , 因为 scanf 输入的时候遇到空格就会停止,所以使用 gets .

(二)逆序原字符串

#include <stdio.h>
#include <string.h>

int main()
{
	char arr[20] = { 0 };
	gets(arr);
	char* left = arr;
	int len = (int)strlen(arr);
	char* right = arr + len - 1;
	while (left < right)
	{
		char temp = *left;
		*left = *right;
		*right = temp;
		left++;
		right--;
	}
	puts(arr);
	return 0;
}

二、单词逆置

题目链接:倒置字符串__牛客网 (nowcoder.com)

题目描述:
 

将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I

 

输入描述:

每个测试输入包含1个测试用例: I like beijing. 输入用例长度不超过100

输出描述:

依次输出倒置之后的字符串,以空格分割

输入

I like beijing.

输出

beijing. like I

先看一下题解代码:

#include <stdio.h>
#include <string.h>	

void reverse(char* left, char* right)
{
	while (left < right)
	{
		char temp = *left;
		*left = *right;
		*right = temp;
		left++;
		right--;
	}
}

int main()
{
	char arr[101] = { 0 };
	gets(arr);
	//逆序整个字符串
	int len = (int)strlen(arr);
	reverse(arr, arr + len - 1);
	
	//逆序每一个单词
	char* start = arr;
	char* end = start;
	while (*start != '\0')//当*start等于\0时,停止逆序
	{
		while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
		{
			end++;
		}
		reverse(start, end - 1);
		if(end != '\0')//如果最后一个单词在向后移动时,会导致start跳过\0从而导致死循环
			end++;
		start = end;
	}
	puts(arr);
	return 0;
}

题解思路:

根据题目描述,倒置字符串跟逆序字符串的思路非常相似,两者的区别在于:倒置字符串是在逆序字符串的基础上再将每一个单词进行逆序,这里逆序单词和逆序一个字符串可以用一个函数来实现(单词本身就是一个字符串)。

下面我们就需要先将整个字符串逆序,然后找到整个字符串中的每一个单词,再将每一个单词进行逆序即可。

这里先说一下,一个单词是如何逆序的:需要两个指针,一个头指针指向单词首字母,一个尾指针指向单词尾字母;第一次将单词的首尾字母交换,头指针向后移动,尾指针向前移动,交换第二对字母,之后是同样的步骤,知道所有字母对都交换完成。

void reverse(char* left, char* right)
{
	while (left < right)
	{
		char temp = *left;
		*left = *right;
		*right = temp;
		left++;
		right--;
	}
}

 

既然要找到每一个单词,那就需要遍历,而单词和单词之间都有一个空格,我们可以用一个字符指针进行遍历,遇到空格时就停一下,空格前的字符串就是一个单词。然后 end 向后移动,此时 end 指向下一个单词的首字母,在将 start 指向与 end 同一个位置的字母,然后再让 end 遍历知道再次遇到空格后停下来。当 start 指向 \0 时停止循环。

    char* start = arr;
	char* end = start;
	while (*start != '\0')//当*start等于\0时,停止逆序
	{
		while (*end != ' ')
		{
			end++;
		}
		reverse(start, end - 1);
        end++;
		start = end;
	}

 但这里要注意,最后一个单词的后面没有空格而是 ‘\0’, 所以当 end 再遇到 '\0' 时也应该停下来,否者到逆序最后一个单词时,就会找不到单词的尾字母了。

所以代码就变成:

while (*start != '\0')//当*start等于\0时,停止逆序
{
	while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
	{
		end++;
	}
	reverse(start, end - 1);
    end++;
	start = end;
}

注意这里的 end 是指向空格的,所以要向指向下一个单词的首字母时,需要 end++.

但是这里还会有一个问题,当遇到最后一个单词时,end 遍历后指向 \0, 当 end++ 后,end 指向 \0 后面的位置,这也就意味着 start 也会指向 \0 后面的位置;还记得逆序字符串的停止条件吗?(*start != '\0'),start 不会指向 \0 循环也就不能够停止了,所以这里并不能让 end 指向 \0 时再向后移动,所以这里需要加一个条件。  代码变为:

    while (*start != '\0')//当*start等于\0时,停止逆序
	{
		while (*end != ' ' && *end != '\0')//注意最后一个单词的后面不是空格
		{
			end++;
		}
		reverse(start, end - 1);
		if(end != '\0')//如果最后一个单词在向后移动时,会导致start跳过\0从而导致死循环
			end++;
		start = end;
	}

逆置字符串基本完成了。

这里还有一些小问题:当输入一个字符串时,你选择使用 fgets ,结果会变为

 这里涉及 fgets 的使用细节 --换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中, 也就是说 \n  也被赋值进字符串中了,所以在打印的时候,Beijing. 后面会有一个换行的操作。

————————————————————————

今天的分享就到这里了,如果,你感觉这篇博客对你有帮助的话,就点个赞吧!感谢感谢……

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值