---
title: "8. String to Integer atoi"
url: "https://laigary.com/interview/coding/8-string-to-integer-atoi"
type: "note"
section: "coding"
date: "2023-01-29"
updated: "2024-03-03"
tags: ["String"]
---

# 8. String to Integer atoi

[8\. String to Integer (atoi)](https://leetcode.com/problems/string-to-integer-atoi/)

這一個題目主要考察的並不是演算法與資料結構，考察的點在於是否可以冷靜地處理邊角案例，在面試中，給出的例子可能並不多，要看看在面試的人是否有辦法清楚的了解題目在幹嘛。

面試官可能就會只貼出下面的例子，並要我們寫出一個程式碼來做轉換，但是千萬不能夠馬上跳進去寫！

```text
"420" -> 420
"-420" -> -420
"420 hello world" -> 420
"hello world 420" -> 0
"    -420   " -> -420

```

不管怎麼樣，要先從給出的這些例子，看看我們可以觀察出什麼事情

1.  如果給定的字串就是一串數字，那結果就會是一串數字，範例中有包含了兩種情況，但是這樣是不夠的：
2.  字串為正整數 -> 直接變成正整數
3.  字串為負整數 -> 直接變成負整數
4.  **如果整數前面有正號呢？** `+420` ？要問到面試官回答你：`420`
5.  **如果是浮點數呢？**要問到面試官回答你：只需要取整數的部分，不用四捨五入，正負號的取法和上面一樣。
6.  **如果說數字前面有很多 0 呢？**`00420` 要問到面試官回答你：`410`
7.  第二種情況，那就是數字和文字同時出現的情況，範例中包含了兩種情況，但是這樣還是不夠的：
8.  題目的開始就是數字，後面所有的文字都捨棄
9.  題目的開始就是文字，後面的就算有數字也回傳回零
10.  如果是數字在文字中間呢？要問到面試官回答，視同 2-2
11.  如果說有兩串文字出現呢？例如：`420 710 hello world` 要問到面試官回答到只要取第一個就好。（這個題目也可以在第一大類情況的時候問，不過我放在這裡是因為，我其實就是到這裡才想到這個例子的，想要表達的是，不用緊張，慢慢的推敲題目，比起寫到一半才發現是這樣，那會悲劇）
12.  其他可以一起在這裡確認的就是如果整個字串都沒有數字，那**基礎情況（Base case）**是什麼？要問到面試官回到 0
13.  第三種情況，這個題目有可能會有很多的空白，和第二種情況不一樣的是，如果說在合法的字元前面有非常多的空白，都是可以忽略不計的，當問到這裡的時候，就可以比較清楚知道題目的規則了。
14.  如果是 `42 0` 那這樣是 `420` 還是 `42` ？要問到面試官回答到 `42`
15.  第四種情況，如果是空字串呢？那要問到面試官回答到答案是 `0` 。

以上是我自己會詢問問題的方式，這個過程看起來很長，但是如果沒有先搞懂這件事情，這個題目其實會變得很困難，這個題目以上的問題其實都可能可以換答案，例如題目可能可以從問一個數字面成一串數字…等，這些其他因素都會影響題目好不好做。

上面的這個推論，甚至可以用文字來表達他的大意，那就是我們要找到一串字串中「第一個的合法整數」，如果字串的開頭不是合法的整數或是正負號，表示此題目無解。

有了以上的情況，題目就不難了，LeetCode 的題目有額外給在正數或負數的情況，答案會怎麼影響，這和面試沒有什麼太大的關係。

```python
class Solution:
    def myAtoi(self, s: str) -> int:
        # 空字串
        if len(s) == 0:
            return 0

        # 都是空白
        arr = list(s.strip())
        if len(arr) == 0:
            return 0

        # 先取正、負號
        sign = -1 if arr[0] == '-' else 1

        # 判斷要出發點
        i = 1 if arr[0] in ['+', '-'] else 0

        # 開始建構答案
        # 1. 如果遇到第一個不是數字的字元，while 就會停止
        # 2. 如果 while 連執行都沒有執行，那答案就是 0 
        res = 0
        while i < len(arr) and arr[i].isdigit():
            res = 10 * res + int(arr[i])
            i += 1


        # LeetCode 才有的條件，面試中可能不會被問到
        if sign == 1:
            return min(res, 2**31-1)
        else:
            return max(-res, -2**31)

```
