2021-09-12:请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。函数 myAtoi(string s) 的算法如下:读入字符串并丢弃无用的前导空格,检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。将前面步骤读入的这些数字转换为整数(即,"123" -> 123, "0032" -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为231 − 1。返回整数作为最终结果。注意:本题中的空白字符只包括空格字符 ' ' 。除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

福大大 答案2021-09-12:

数位用负数。注意两个byte的数字相减,始终是正数,不可能是负数。

代码用golang编写。代码如下:

package main

import (
    "fmt"
    "math"
    "strings"
)

func main() {
    ret := myAtoi(" +0123456 ")
    fmt.Println(ret)
}

func myAtoi(s string) int {
    if s == "" {
        return 0
    }
    s = removeHeadZero(strings.Trim(s, " "))
    if s == "" {
        return 0
    }
    str := []byte(s)
    if !isValid(str) {
        return 0
    }
    // str 是符合日常书写的,正经整数形式
    posi := true
    if str[0] == '-' {
        posi = false
    }
    minq := math.MinInt64 / 10
    minr := math.MinInt64 % 10
    res := 0
    cur := 0
    for i := twoSelectOne(str[0] == '+' || str[0] == '-', 1, 0); i < len(str); i++ {
        // 3  cur = -3   '5'  cur = -5    '0' cur = 0
        cur = int('0') - int(str[i])
        if (res < minq) || (res == minq && cur < minr) {
            return twoSelectOne(posi, math.MaxInt64, math.MinInt64)
        }
        res = res*10 + cur
    }
    // res 负
    if posi && res == math.MinInt64 {
        return math.MaxInt64
    }
    return twoSelectOne(posi, -res, res)
}

func twoSelectOne(c bool, a int, b int) int {
    if c {
        return a
    } else {
        return b
    }
}

func removeHeadZero(str string) string {
    r := strings.Index(str, "+") == 0 || strings.Index(str, "-") == 0
    s := 0
    if r {
        s = 1
    }
    for ; s < len(str); s++ {
        if str[s] != '0' {
            break
        }
    }
    // s 到了第一个不是'0'字符的位置
    e := -1
    // 左<-右
    for i := len(str) - 1; i >= twoSelectOne(r, 1, 0); i-- {
        if str[i] < '0' || str[i] > '9' {
            e = i
        }
    }
    //return str[s:twoSelectOne(e == -1, len(str), e)]
    // e 到了最左的 不是数字字符的位置
    ans := ""
    if r {
        ans = fmt.Sprintf("%c", str[0])
    }
    ans = ans + str[s:twoSelectOne(e == -1, len(str), e)]
    return ans
}

func isValid(chas []byte) bool {
    if chas[0] != '-' && chas[0] != '+' && (chas[0] < '0' || chas[0] > '9') {
        return false
    }
    if (chas[0] == '-' || chas[0] == '+') && len(chas) == 1 {
        return false
    }
    // 0 +... -... num
    for i := 1; i < len(chas); i++ {
        if chas[i] < '0' || chas[i] > '9' {
            return false
        }
    }
    return true
}

执行结果如下:
图片


左神java代码