[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
}

猜你喜欢

转载自blog.csdn.net/trinityleo5/article/details/132323001