【LeetCode】【字符串】【位运算实现字母大小写转换】709. 转换成小写字母 Java实现


题目链接

https://leetcode.cn/problems/to-lower-case/

题目

在这里插入图片描述

官方思路

方案一 Java API实现大小写转换

String类的常用方法包括:

String toLowerCase():使用默认语言环境,将String中所有字符转换为小写

String toUpperCase():使用默认语言环境,将String中所有字符转换为大写

class Solution {
    public String toLowerCase(String s) {
        return s.toLowerCase();
    }
}

方案二 哈希表

使用一个哈希映射,哈希映射中包含26个键值对(A,a),(B,b),(C,c),…,(Z,z)。对于每一个待转换的字符ch,如果它出现在哈希映射中(即ch时哈希映射中的一个键),那么ch是大写字母,我们直接获取ch在哈希映射中的值即可得到对应的小写字母;如果它没有出现在哈希映射中,那么ch是其他字符,我们无需进行转换

然而,这种方法需要一定的辅助空间,不够简洁

方案三 位运算实现大写到小写转换(巧妙)

一种更好的方法就是观察小写字母和大写字母的ASCII表示:

  • 大写字母 A - Z 的ASCII码范围为[65,90]
  • 小写字母 a - z 的ASCII码范围是[97,122]

进而可以发现,对于[65,90]对应的二进制表示为[ 0100 0001 , 0101 1010 ],32对应的二进制表示为 0010 0000,对于[ 0100 0001 , 0101 1010 ]内的所有数,表示32的那个二进制位都是0,因此。可以对ch的ASCII码与32做按位或运算,代替与32的加法运算

class Solution {
    public String toLowerCase(String s) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 65 && c <= 90){
                c |= 32;
            }
            builder.append(c);
        }
        return builder.toString();
    }
}

扩展 - 位运算实现字母大小写转换

大写转小写

字符 与 32 按位或运算(上面已经解释)

小写转大写

字符与 -33 按位与运算

-33 的 二进制表示为 1101 1111

对于[97,122]对应的二进制表示为[ 0110 0001 , 0111 1010 ],32对应的二进制表示为 0010 0000,对于[ 0110 0001 , 0111 1010 ]内的所有数,表示32的那个二进制位都是1,因此。可以对ch的ASCII码与-33做按位与运算,代替与32的减法运算

借着上面那一题的测试程序测试一下:

class Solution {
    public String toLowerCase(String s) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= 97 && c <= 122) {
                c &= (-33);
            }
            builder.append(c);
        }
        return builder.toString();
    }
}

输入:

"Hello"
"here"
"LOVELY"

输出:

"HELLO"
"HERE"
"LOVELY"

最终封装好的转换成大写字母的函数为:

public String toUpperCase(String s) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c >= 97 && c <= 122) {
            c &= (-33);
        }
        builder.append(c);
    }
    return builder.toString();
}

大写变小写,小写变大写

字符 与 32 按位异或运算

通过上面的分析可以知道:

  • 大写字母 A - Z 的ASCII码范围为[65,90]

    • 对于[65,90]对应的二进制表示为[ 0100 0001 , 0101 1010 ],32对应的二进制表示为 0010 0000,对于[ 0100 0001 , 0101 1010 ]内的所有数,表示32的那个二进制位都是0
  • 小写字母 a - z 的ASCII码范围是[97,122]

    • 对于[97,122]对应的二进制表示为[ 0110 0001 , 0111 1010 ],32对应的二进制表示为 0010 0000,对于[ 0110 0001 , 0111 1010 ]内的所有数,表示32的那个二进制位都是1

所以,可以进行按位异或运算,异或运算的口诀是:相同为0,不同为1

如果是大写字母[65,90],表示32的二进制位是0,与32进行异或,0就会变成1,实现加32的操作,从而转换成小写字母

如果是小写字母[97,122],表示32的二进制位都是1,与32进行异或,1就会变成0,实现减32的操作,从而转换成大写字母

同样,借LeetCode的测试程序验证一下:


输入:

"Hello"
"here"
"LOVELY"

输出:

"hELLO"
"HERE"
"lovely"

最终封装好的字母大小写转换的函数为:

public String toChangeCase(String s) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if ((c >= 97 && c <= 122) || (c >= 65 && c <= 90)) {
            c ^= 32;
        }
        builder.append(c);
    }
    return builder.toString();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值