8. 字符串转换整数 (atoi)
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [-2^31, 2^31 - 1]。如果数值超过这个范围,qing返回 INT_MAX (2^31 - 1) 或 INT_MIN (-2^31) 。
// 运行 4ms, 大部分都是4ms 左右的运行时间
package main
import (
"fmt"
"strings"
"math"
)
// 私有 atoi 转换
// 在任何情况下,若函数不能进行有效的转换时,请返回 0。
// " -42" -> -42
//输入: "4193 with words"
//输出: 4193
//输入: "words and 987"
//输出: 0
//输入: "-91283472332" < math.MinInt32
//输出: -2147483648
func myAtoi(str string) int {
if str == "" {
return 0
}
// 有空格前缀则全部替换
for strings.HasPrefix(str," ") {
str = str[1:]
}
if str == "" {
return 0
}
// 正负符号判定
sign := 1
for str[0] == 45 || str[0] == 43{
if str[0] == 45{
sign = -1
str = str[1:]
break
}
if str[0] == 43{
sign = 1
str = str[1:]
break
}
}
if str == "" {
return 0
}
for strings.HasPrefix(str,"0") {
str = str[1:]
}
if str == "" {
return 0
}
tmp := []int{}
for _,v := range str {
// ASCII 码 , 57 -> 9 , 48 -> 0
if v > 57 || v < 48 {
break
} else {
tmp = append(tmp,int(v-48))
}
}
//fmt.Println(tmp)
// 没有数字返回0
if len(tmp) == 0 {
return 0
}
// 简单越界处理
if len(tmp) > 10 || (len(tmp) == 9 && tmp[0] > 2){
if sign == 1 {
return math.MaxInt32
}
if sign == -1 {
return math.MinInt32
}
}
j:=len(tmp)-1
tmpInt := 0
for i:=0;i<len(tmp);i++{
tmpInt += tmp[i] * pow10(j)
j--
}
if tmpInt > math.MaxInt32{
if sign == -1 {
return math.MinInt32
} else {
return math.MaxInt32
}
}
return tmpInt * sign
}
func pow10(i int)int{
if i == 0 {
return 1
}
rst := 1
for ;i>0;i--{
rst *= 10
}
return rst
}
func main() {
fmt.Println(myAtoi("-+2"))
}