每日一练---翻转字符串里的单词

题目描述
在每日一练中有一道反转字符串里单词的题目,具体如下:
给定一个字符串,逐个翻转字符串中的所有单词 。单词是由非空格字符组成的字符串。至少有一个空格将字符串中的单词分隔开。
要求:
1、返回一个翻转字符串中单词顺序并用单个空格相连的字符串。
2、给定的输入字符串可以在前面、后面或者单词间包含多余的空格。
3、翻转后单词间应当仅用一个空格分隔。
4、翻转后的字符串中不应包含额外的空格。
标准答案中使用了栈来处理,我想用其他比较简单,容易理解的方式处理,同时不考虑时间复杂度。

想法思路
首先想到的是字符串翻转中使用的递归方法,但是并不容易实现。最后决定将每个单词首字母在字符数组中的下标取出,然后根据下标输出每个单词,注意单词间的空格即可。

代码编写
首先给定两个数组,一个用于存储给定字符串,一个放首字母下标:

    char str[50] = " nothing is impossible ";
    char index[50] = {0};

然后根据前一个字符是空格来确定首字母,并保存其下标:

	while(str[i] != '\0')
	{
		if(i == 0 && str[i] > 0x20) j++; 
		else if(str[i - 1] == 0x20 && str[i] > 0x20) index[j++] = i;
		i++;
	}

这里加入i == 0的判断是因为1、给定字符串有可能第一个字符是空格,此时就需要else if来判断index[0]的值,若不是空格,index[0] = 0;2、else if的判断条件在i是0时不能使用。

之后反序循环index,根据下标将单词输出,注意单词之间加一个空格,完整程序如下:

#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    char str[50] = " nothing is impossible ";
    char index[50] = {0};
    
    int i,j,outIndex;
    i = j = 0;
      
	while(str[i] != '\0')
	{
		if(i == 0 && str[i] > 0x20) j++; 
		else if(str[i - 1] == 0x20 && str[i] > 0x20) index[j++] = i;
		i++;
	}
	
	for(i = j - 1;i >= 0;i--)
	{
		outIndex = index[i];
		while(str[outIndex] != '\0' && str[outIndex] > 0x20)
		{
			cout << str[outIndex];
			outIndex++;
		}
		cout << " ";
	}
	
    return 0;
}

不论字符串中空格在哪里,如程序中给定的字符串中前后均有多余的空格,输出字符串中只有每个单词间一个空格:
在这里插入图片描述
小插曲
在程序第一次编写完成进行测试时,如果字符串开头有空格,输出就不正确,最后查出问题出在定位首字母的部分,其初始代码如下:

	while(str[i++] != '\0')
	{
		if(i == 0 && str[i] > 0x20) j++; 
		else if(str[i - 1] == 0x20 && str[i] > 0x20) index[j++] = i;
	}

问题就出现在while语句上,while语句是先执行str[i] != ‘\0’,然后i++,再执行循环体部分。这样就导致i第一次进入循环体就为1,if判断语句就失效了,index[0]始终等于0,所以当字符串开头有空格显示就不完整。
由此可以看出while与for在处理i++等自增自减运算上的不同,for总是在循环体之后再执行,而while则是再循环体之前,具体for的实验可以参看我之前的文章:
for循环测试题的小错误
while也可以做一些实验来验证,首先用for写出如下程序:

#include <stdio.h>
int main()
{
    int i = 0;
    
    for(;i <= 10;i++) printf("%d ",i);
    
    return 0;
}

结果如下:
在这里插入图片描述
执行部分改为while:

	int j = 0;
    
    while(j++ <= 10) printf("%d ",j);

在这里插入图片描述
可以看出明显的不同,while判断条件中的自加运算确实在循环体之前执行。等价于:

    while(j <= 10)
    {
    	j++;
    	printf("%d ",j);
	}

而do…while也同样适用:

	do
	{
		printf("%d ",j);
	}while(j++ <= 10);

等价于:

	printf("%d ",j);
	do
	{
		j++;
		printf("%d ",j);
	}while(j <= 10);

其结果均为:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cedar_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值