Reverse Words in a String

   笔者近来开始在LeetCode上学习常用的算法设计,大家也都知道LeetCode追求的是高性能,而不是说只要能解决问题就可了。因此,我有个想法:这次要把自己设计算法时的所思所想记录下来,和大家分享。也更为了抛砖引玉,和大家交流,希望有更好改进设计的能够和我分享。而自己在这个系列学习中主要采用C++语言,当然之后会跟进Python版的。下面,不在啰嗦,开始本文的正题。

题目原文要求(摘抄自LeetCode):

Given an input string, reverse the string word by word.

For example,
Given s = "the sky is blue",
return "blue is sky the".

Clarification:

  • What constitutes a word?
    A sequence of non-space characters constitutes a word.
  • Could the input string contain leading or trailing spaces?
    Yes. However, your reversed string should not contain leading or trailing spaces.
  • How about multiple spaces between two words?
    Reduce them to a single space in the reversed string.
题目解析:

   从题目中,我们可以看到该题要求按单词反置字符串,而且在详细说明中,解释了:由空格分割的一系列非空字符就是一个单词;还要求你的算法要能处理包含前置/后置空格的情况,而且反置后的字符串不能包含前置/后置空格;还有就是要能够处理两个词之间包含多个空格的情况,将反置后的字符串,单词之间的空格全部变为一个空格。

我的解题思路:

   一看到题目,我是这样想的,我可以按如下步骤处理:

       1. 可以借鉴C#、JavaScript等语言中的字符函数trim(),写一个自己的trim()函数,在算法处理之前首先调用该函数,处理掉首尾的空格;

        2. 从尾部开始遍历该字符串,设置两个标记变量,记录下空格和非空格字符的数量,设置一个临时变量用来存储反置后的字符串,每遇到一个单词就存储下来,遇到空格就压缩为一个空格,直到遍历到头部为止。

    按照这种思路,我写出了自己的解决方案,如下所示:

class Solution {
public:
    void trim(string &s)
    {
	int a = s.find_first_not_of(" ");
	if (a == -1)
	{
		s = "";
		return;
	}
	else if (a != 0)
	{
		s = s.substr(a, s.size() - a);
	}
	a = s.find_last_not_of(" ");
	if (a != s.size() - 1)
	{
		s = s.substr(0, a + 1);
		return;
	}
    }
    void reverseWords(string &s) {
    trim(s);
    if (s == "")
    {
        return;
    }
	string temp = "";
	int i = s.size() - 1;
	int count = 0;
	int sCount = 0;
	while ( i >= 0)
	{
		if (s[i] != ' ')
		{
			count++;
			i--;
			sCount = 0;
		}
		else
		{
		    sCount++;
		    if (sCount == 1)
		    {
			    temp += s.substr(i, count + 1);
		    }
			i--;
			count = 0;
		}
	}
	temp += " " +  s.substr(0, count);
	s = temp;
	trim(s);
    }
};
难点分析(几个临界点需要特别注意):

    1. 一定要处理字符串全空的特殊情况;

    2. 当遇到第一个空格的时候来截取刚刚遍历到的单词,而且注意两个单词之间只能出现一个空格,一次要添加if (sCount==1)的判断,否则你处理后的字符串,每个单词之间就会出现多个空格,出现如下的错误:


 

   3. 要处理第一个单词的临界情况,注意在后面添加一个空格,否则反置后最后两个单词就会连在一起,如下所示(第一行为输入,第二行是输出):

   4. 要将处理完后的字符串再次调用一次trim()函数,否则就会出现下面的情况:

结果:

    经过上面的分析,最终笔者的算法在线测试也通过了,最后的结果如下:

其他实现途径:

   其实,还有很多解题思路,我在这里指简要的说一下我同学的做法吧。他首先,将字符串整个反置,然后再将每个单词反置,同时处理首尾字符和单词之间的多余字符,这里代码就不在给出了,有兴趣的可以自己实现一下啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值