[倒置字符串]


前言

大家好,我是熊猫,今天要和大家一起学习的是牛客网上一道编程题----倒置字符串,本题解法多样,熊猫今天整理了三种不同的解法,希望可以给大家提供不同的解题思想。


一、题目描述

将一句话的单词进行倒置,标点不倒置。比如 “I like beijing.”,经过处理后变为:“beijing. like I”。
字符串长度不超过100。

输入描述:
输入一个仅包含小写字母、空格、‘.’ 的字符串,长度不超过100。
‘.’ 只出现在最后一个单词的末尾。

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

二、题目解析

(一)解法1

首先我们一起来分析分析这道题,‘将一句话的单词进行倒置,标点不倒置’,那么我们首先想到的可能就是从后往前将单词逆序拿出来,这种方法当然是行得通的,那我们就需要创建一个新的数组来存放取出来的单词,同时大家需要注意最后的‘.’不要忘记了。

下面函数中调用了一个assert函数,我们需要在前方引用头文件<assert.h>
它的用途是判断条件是否为真,在debug环境下可以当做 if语句来看待

代码如下(示例):

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<assert.h>
char* inv(const char str[], char arr[], const int sz) {
assert(str && arr);//断言(判断)
int right = sz - 1;
int left = right;
int i = 0;
for (; right >= 0; right--) {
    if (str[right] == ' ' || right == 0) {
    //单词与单词之间都有空格间隔,遇到空格就讲它之后的单词复制到arr数组中
        if (right == 0)
            left = 0;
        else
            left = right + 1;
        do {
            arr[i++] = str[left++];//这样可以直接将空格也同时录入
            if (str[left] == '\0')
                arr[i++] = ' ';
        } while (isalpha(arr[i - 1]));//<ctype.h>中的函数,该字符是字母返回1,否则返回0
    }
}
    arr[i] = '\0';
return arr;
}

int main() {
char str[101] = { 0 };//字符串长度不超过100,最后还有一个'\0'
gets(str);//由于scanf遇到空格或者换行会停止读取数据,所以这里使用gets(读取字符串)
char arr[101] = { 0 };
int sz = strlen(str);//求字符串长度,不包括'\0'
printf("%s\n", inv(str, arr, sz));
return 0;
}

(二)解法2

这里我们来认识一种很巧妙的方法,先将每个单词进行逆序,之后再将整个字符串进行逆序,这种方法还有一个优点就是:不用考虑空格与’\0’。

代码如下(示例):

void reverse(char str[], int left, int right) {
	assert(str);
	while (left <= right) {
		char ch = str[left];
		str[left] = str[right];
		str[right] = ch;
		left++;
		right--;
	}
}

int main() {
	char str[101] = { 0 };
	gets(str);
	int sz = strlen(str);
	int i = 0;//用来记录单词最后一个字母的下标(最后的句号也算在单词里)
	int j = 0;//用来记录单词第一个字母的下标
	for (i = 0; i <= sz; i++) {
		if (str[i] == ' ' || str[i] == '\0') {
			reverse(str, j, i - 1);//每个单词进行倒置
			j = i + 1;
		}
	}
	reverse(str, 0, sz - 1);//整个句子进行倒置
	printf("%s\n", str);
	return 0;
}

(三)解法3

下面我们介绍一种“偷鸡”取巧的方法,通过递归,将每一个单词存在一个字符串中,倒序输出。

代码如下(示例):

void fun() {
	char str[101] = { 0 };
	if (scanf("%s", &str) != EOF) {//EOF一般是-1,当数据读取失败时会返回EOF,自行测试的时候按“Ctrl+z”结束
		fun();
	printf("%s ", str);//scanf遇到空格就停止读取,所以空格需要我们自行输出
	}
}

int main() {
	fun();
	return 0;
}

总结

以上就是熊猫对这个题目的理解,顺带一提:题解一的适用范围很小,甚至可以说只使用与题目这种情况,如果再增加其他字符那就很可能得不到我们想要的结果,而如果递归使用的不是那么精通的话,题解三是很难想到的,所以大家做题时尽可能地使用解法二。
如果大家还有其他好的做法欢迎在评论区留言,大家的点赞与收藏在这里插入图片描述不断更新的动力,感谢大家的支持。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值