
String to Integer (atoi)
這次的規則比較長, 共有以下5點規則
1. 依序讀入字元, 並且忽略空白(” “)
2. 檢查下一個字元(如果還沒到字串結尾), 是 – 還是 +, 如果存在就存入結果字串, 這將決定答案是正還是負數, 如果都沒有,那答案就輸出正數
3. 持續讀入下一個字元, 直到碰到非數字字元或者輸入字串的結尾, 碰到非數字字元, 就放棄後面不用輸入了
4. 如果這串輸入都沒讀到數字, 就回傳 0, 轉換讀到的數字成為整數(‘123’ -> 123, ‘001234’-> 1234), 轉換後的數字要看項目2 檢查到的 +- 去轉換
5. 輸出的數字範圍只能是整數範圍 [-231, 231 – 1], 超過的話就回傳 -231 or 231 – 1
然後…看得懂英文真的重要, 很多字分開看得懂, 組起來就霧煞煞, 導致一開始解題方向錯了, 好險後來翻譯跟試錯之後有快點調回來
解題脈絡
因為限制不少, 所以一開始先看, 是否有已經被讀到數字, 然後下一個字元不是數字, 接下來判斷 +- 號是不是第一個出現, 然後空白不理他, 最後去確認度進來的字串是不是數字, 是的話就轉組起來, 最後用atoi 轉成 數字, 看看是不是在整數範圍內, 接著傳出答案
寫法
func myAtoi(s string) int {
if len(s) == 0 {
return 0
}
temp := ""
fristword := 0
for i := 0; i < len(s); i++ {
if fristword != 0 && len(temp) != 0 && !unicode.IsNumber(rune(s[i])) {
_, err := strconv.Atoi(temp)
if (s[i] == '-' || s[i] == '+') && err != nil {
return 0
}
break
}
if s[i] == ' ' && fristword == 0 {
continue
}
if (s[i] == '-' || s[i] == '+') && fristword == 0 {
fristword++
temp = fmt.Sprintf("%v%v", temp, string(s[i]))
}
if !unicode.IsNumber(rune(s[i])) && fristword == 0 {
return 0
}
if unicode.IsNumber(rune(s[i])) {
temp = fmt.Sprintf("%v%v", temp, string(s[i]))
fristword++
}
}
if temp == "" {
return 0
}
res, _ := strconv.Atoi(temp)
if res > (1<<31)-1 {
return (1 << 31) - 1
}
if res < -(1 << 31) {
return -(1 << 31)
}
return res
}