目录
- 题目:转换成小写字母
- 思路分析:大写字母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 := 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
}