目录
- 题目:转换成小写字母
- 思路分析:大写字母ASCII码 + 32 = 小写字母ASCII码
- Go代码
- Go代码-优化: 大写字母ASCII码 | 32 = 小写字母ASCII码
- 题目:字符串转换整数(atoi)
- 思路分析:去除首部空格 + 明确正负 + 读取数字 + 判断越界
- 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,如果第一个有效字符== ‘-’ 就是-1
- 读取数字:
- 字符 0-9 的 ASCII 码范围为 [48,57],所以通过字符的 ASCII 码值减去 48 可获得相应的数字
- 值的拼装为 res = res * 10 + v * sign
- 判断越界:
- 超过最大值:res > (math.MaxInt32-v) / 10
- 小于最小值:res < (math.MinInt32+v) /10
Go代码
func myAtoi(s string) int {ret := 0i := 0length := 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*vi++} 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
}