剑指 Offer 58 - I. 翻转单词顺序-split-trim

思路:

(1)把单词中多余空格去掉:包括了单词前端的空格,单词后端的空格,和单词中间的空格。
(2)将字符串整体翻转
(3)将其中的单词单独翻转
例如

"    I    am   a  coder!    ";
// 经过第一步之后变为了
"I am a coder!";
// 经过第二步之后变为了
"!redoc a ma I"
// 经过第三步之后
"coder! a am I"

代码实现

public class Solution01 {
    public String reverseWords(String s) {
        if (s == null || s.length() == 0) {
            return s;
        }
        // 去掉空格,存入strBuilderRes中
        StringBuilder strBuilderRes = new StringBuilder();
        int slow = 0;
        int fast = slow;
        while (slow < s.length()) {
            // slow 指向每一个单词的开始
            while (slow < s.length() && s.charAt(slow) == ' ') {
                slow++;
            }
            // / fast 指向每一个单词后的第一个空格
            for (fast = slow; fast < s.length(); fast++) {
                if (s.charAt(fast) == ' ') {
                    break;
                }
            }
            if (slow < s.length()) {
                String subStr = s.substring(slow, fast);
                strBuilderRes.append(subStr);
                strBuilderRes.append(' ');
                slow = fast;
            }
        }
        // 删除末尾多余的空格(我们自己添加的),并整体翻转
        if (strBuilderRes.length() > 0) {
            strBuilderRes.deleteCharAt(strBuilderRes.length() - 1);
            strBuilderRes.reverse();
        }
        // 在把每个单词翻转
        slow = 0;
        while (slow < strBuilderRes.length()) {
            for (fast = slow; fast < strBuilderRes.length(); fast++) {
                if (strBuilderRes.charAt(fast) == ' ') {
                    break;
                }
            }
            StringBuilder subStrBuilder = new StringBuilder(strBuilderRes.substring(slow, fast));
            subStrBuilder.reverse();
            strBuilderRes.replace(slow, fast, subStrBuilder.toString());
            slow = fast + 1;
        }
        return strBuilderRes.toString();
    }

    public static void main(String[] args) {
        String str = " ";
        System.out.println(new string.Offer058.Solution01().reverseWords(str));
    }
}

主要记录一下自己的遇到的坑

String subStr = s.substring(slow, fast);

上面这个函数调用,提取子串的语义是 s[slow, fast),是左闭右开的一个区间。但是如果s的长度是8slow是可以取到8的,即下面的代码提取出来的子串为"",但是slowfast都不能超过8,否则会报错

String subStr = s.substring(8, 8);

所以在提取子串的时候得判断一下,slow < s.length()

偷懒的方法

trim() 方法:用以去除字符串开头和结尾的所有空格

如果不想看解释,直接看(7),会用就行了
在这里插入图片描述
上图是trim()函数的原型以及相关说明,简单翻译就是:
(1)trim()String类的一个共有方法,返回值类型是String
(2)返回一个字符串,其中的值是this指向的字符串(直白来说,就是调用这个方法的字符串),但是和this指向的字符串相比,去掉了头部和尾部的空白符
在这里插入图片描述
(3)如果this指向的字符串是一个空串(不是null,而是长度为0),trim()就返回这个字符串本身
在这里插入图片描述
在这里插入图片描述

(4)如果this指向的字符串第一个字符和最后一个字符的代码单元都大于\u0020,(\u0020代表空格),trim()就返回这个字符串本身,(那么小于\u0020的都是什么字符呢?\u0020是十六进制,十进制代表了32,是第33个字符,前32个都是控制字符,不可显示的,所以我们常见的字符都是大于\u0020的)。这段话翻译成人话就是,如果一个字符串开头和结尾都不是空格(因为我们能看见的字符都大于\u0020),那么就返回这个字符串本身
在这里插入图片描述
在这里插入图片描述
u\0021大于\u0020,代表了!\u0023代表了#

(5)如果字符串中所有的字符的代码单元都小于\u0020,那么就返回一个空串
在这里插入图片描述

(6)其余情况:就返回一个子串,this.subString(k, m + 1)k:字符串第一个代码单元大于\u0020m:字符串最后一个代码单元大于\u0020说人话就是,将头尾的空格都去掉,内部调用subString取子串返回,其实也可以去掉小于\u0020的代码单元,但是这些字符不可见
在这里插入图片描述
在这里插入图片描述
(7)trim()就是去掉这个字符串头尾的空格,中间的不去掉,并返回一个新的字符串;如果头尾没有空格,就返回这个字符串本身。对返回值的理解,也体现了字符串的不可变性

split()方法

在这里插入图片描述
以给定的正则表达式分割字符串,\s匹配任何空白符,\s+表示多个,\\s+,表示在Java中使用,加上转义。和trim()联合使用就可以实现,先去头尾空格,然后将字符串分割,中间包含多个连续的空格也能分割开来。

String str3[] = str2.trim().split("\\s+");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值