😇

2022/07/31に公開

# String to Integer (atoi)

## 問題文

``````Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer (similar to C/C++'s atoi function).

The algorithm for myAtoi(string s) is as follows:

Check if the next character (if not already at the end of the string) is '-' or '+'. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present.
Read in next the characters until the next non-digit character or the end of the input is reached. The rest of the string is ignored.
Convert these digits into an integer (i.e. "123" -> 123, "0032" -> 32). If no digits were read, then the integer is 0. Change the sign as necessary (from step 2).
If the integer is out of the 32-bit signed integer range [-231, 231 - 1], then clamp the integer so that it remains in the range. Specifically, integers less than -231 should be clamped to -231, and integers greater than 231 - 1 should be clamped to 231 - 1.
Return the integer as the final result.
Note:

Only the space character ' ' is considered a whitespace character.
Do not ignore any characters other than the leading whitespace or the rest of the string after the digits.
``````

## 日本語 by DeepL

myAtoi(string s)のアルゴリズムは以下の通りである。

これらの数字を整数に変換する (すなわち、"123" -> 123, "0032" -> 32) 。桁が読み取れなかった場合、整数は0である。必要に応じて符号を変更する（ステップ2から）。

www.DeepL.com/Translator（無料版）で翻訳しました。

## 例題

``````Input: s = "42"
Output: 42
Explanation: The underlined characters are what is read in, the caret is the current reader position.
Step 1: "42" (no characters read because there is no leading whitespace)
^
Step 2: "42" (no characters read because there is neither a '-' nor '+')
^
Step 3: "42" ("42" is read in)
^
The parsed integer is 42.
Since 42 is in the range [-231, 231 - 1], the final result is 42.
``````

## 検討

ちなみにparseIntを使ってしまえば簡単。

どちらかというとparseIntを使わずにコツコツ解いたほうが面白いかもしれない。
+と-の扱いとかそのあたりが大変なのだ。

## 回答

``````function myAtoi(s: string): number {
/*
とりあえず両端の空白を消しておく
文字列がなくなったら0を返す
*/
const trimmedS = s.trim();
if (trimmedS === "") return 0;

/*
parseInt使ったら簡単……。
10進数ということを明示する。
isNanのときは0を返す
*/
const parsedInt = parseInt(trimmedS, 10);
if (isNaN(parsedInt)) return 0;

/*
最小が決まっているので、それより小さいなら最小値を返す
-2の31乗は-2147483648だけど、powで計算しておく
*/
const minRange = Math.pow(-2, 31);
if (parsedInt < minRange) return minRange;

/*
最大が決まっているので、それより大きいなら最大値を返す
2の31乗-1は2147483647だけど、powで計算しておく
でもべつに問題文に書かれてるなら定数にしても良い気がする。
わざわざ計算する必要あるのかな
*/
const maxRange = Math.pow(2, 31) - 1;
if (parsedInt > maxRange) return maxRange;

/* parseIntを使えば簡単 */
return parsedInt;
}
``````

1. 両端の空白を消す
2. 空白消してなくなったら0
3. 10進数でパースする
4. おかしな数字だったら0
5. 最小値超えてたら最小値にする
6. 最大値超えてたら最大値にする
7. 終わり

ログインするとコメントできます