[Go版]算法通关村第十二关青铜——不简单的字符串转换问题

题目:转换成小写字母

题目链接:LeetCode-709. 转换成小写字母
在这里插入图片描述

思路分析:大写字母ASCII码 + 32 = 小写字母ASCII码

  • 大写字母 A - Z 的 ASCII 码范围为 [65,90]
  • 小写字母 a - z 的 ASCII 码范围为 [97,122]
    所以,只要字符的ASCII码再[65,90]的范围内,将它增加32即可得到对应的小写字母。

Go代码

func toLowerCase(s string) string {
    ret := make([]rune, len(s))
    for i, v := range s {
        if v >= 'A' && v <= 'Z' {
            ret[i] = v + 32
        } else {
            ret[i] = v
        }
    }
    return string(ret)
}

Go代码-优化: 大写字母ASCII码 | 32 = 小写字母ASCII码

[65,90]对应的二进制表示为[ (01000001)2,(01011010)2 ]
32对应的二进制表示为 (00100000)2
对于[ (01000001)2,(01011010)2 ] 内的所有数,表示32的那个二进制位都是0,所以可以对其ASCII码与32做按位或运算,替代与32的加法运算

上面使用了[]rune切片来存储新的字符,这里我们换种写法,使用strings.Builder来构建字符串

func toLowerCase(s string) string {
    str := &strings.Builder{}
    str.Grow(len(s))
    for _, v := range s {
        if v >= 65 && v <= 90 {
            str.WriteRune(v | 32)
        } else {
            str.WriteRune(v)
        }
    }
    return str.String()
}

题目:字符串转换整数(atoi)

题目链接:LeetCode-8. 字符串转换整数 (atoi)
在这里插入图片描述

思路分析:去除首部空格 + 明确正负 + 读取数字 + 判断越界

  1. 去除首部空格:== ’ ’ 就跳过
  2. 明确正负:默认为1,如果第一个有效字符== ‘-’ 就是-1
  3. 读取数字:
    • 字符 0-9 的 ASCII 码范围为 [48,57],所以通过字符的 ASCII 码值减去 48 可获得相应的数字
    • 值的拼装为 res = res * 10 + v * sign
  4. 判断越界:
    • 超过最大值:res > (math.MaxInt32-v) / 10
    • 小于最小值:res < (math.MinInt32+v) /10

Go代码

func myAtoi(s string) int {
    ret := 0
    i := 0
    length := len(s)
    sign := 1
    // 去除首部空格
    for _, v := range s {
        if v == ' ' {
            i++
        } else {
            break
        }
    }
    // 获得+-
    if i < length && (s[i] == '+' || s[i] == '-') {
        sign = getSign(s[i])
        i++
    }
    // 读取数字
    for i<length {
        if s[i] >= '0' && s[i] <= '9' {
            v := getIntByChar(s[i])
            // 判断越界问题
            if MoreThanMax(ret, v) || LittleThanMin(ret, v) {
                if sign == 1 {
                    return math.MaxInt32
                }
                return math.MinInt32
            }
            ret = ret*10 + sign*v
            i++
        } else {
            return ret
        }
    }
    return ret
}
func getSign(str byte) int {
    if str == '-' {
        return -1
    }
    return 1
}
func getIntByChar(ch byte) int {
    return int(ch-'0')
}
func MoreThanMax(ret, v int) bool {
    if ret > (math.MaxInt32-v)/10 {
        return true
    }
    return false
}
func LittleThanMin(ret, v int) bool {
    if ret < (math.MinInt32+v)/10 {
        return true
    }
    return false
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值