Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions 競技プロ就活部PR用/8. String to Integer (atoi).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
解けなかったため、他参加者の答えを参考に何度か書いてみた後、自力で再現。
### 1回目
時間計算量: O(N)<br>
空間計算量: O(N)<br>
N: len(s)

```python
class Solution:
def myAtoi(self, s: str) -> int:
s = s.lstrip()
if not s:
return 0

negative_flag = False
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_negativeとかの方が良いかなと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。flagで片付けてしまうことがあるので、覚えておきます。

index = 0
if s[index] == "-" or s[index] == "+":
if s[index] == "-":
negative_flag = True
index += 1

digits_str = ""
while index < len(s):
if s[index].isdigit():
digits_str += s[index]
index += 1
else:
break
if not digits_str:
return 0

digits_int = int(digits_str)
if negative_flag:
digits_int *= -1

MAX_INT = 2 ** 31 - 1
MIN_INT = -2 ** 31
if digits_int > MAX_INT:
return MAX_INT
elif digits_int < MIN_INT:
return MIN_INT
else:
return digits_int
```

### 2回目
他参加者の回答を参考に、下記を書き換えてみる。
- lstripを自前で実装。
- negative_flagをsignに変更。
- 符号の条件判定を、in ('-', '+')に変更。
- INT_MAX, INT_MINをビット演算で実装。
- intへの変換を自前で実装。(ordの利用)
- 実装後、各種フラッグなどの変数を上に移動。

sを直接いじるより、indexを動かしていく方がわかりやすくかつsを壊さないため安心かと思った。

```python
class Solution:
def myAtoi(self, s: str) -> int:
index = 0
sign = 1
MAX_INT = (1 << 31) - 1
MIN_INT = - (1 << 31)

while index < len(s) and s[index].isspace():
index += 1
if index == len(s):
return 0

if s[index] in ('-', '+'):
if s[index] == '-':
sign = -1
index += 1
if index == len(s):
return 0

final_integer = 0
while index < len(s) and s[index].isdigit():
digit = ord(s[index]) - ord('0')
final_integer = 10 * final_integer + sign * digit
if final_integer > MAX_INT:
return MAX_INT
if final_integer < MIN_INT:
return MIN_INT
index += 1

return final_integer
```

### 3回目
```python
class Solution:
def myAtoi(self, s: str) -> int:
index = 0
sign = 1
MAX_INT = (1 << 31) - 1
MIN_INT = - (1 << 31)

while index < len(s) and s[index].isspace():
index += 1
if index == len(s):
return 0

if s[index] in ('+', '-'):
if s[index] == '-':
sign = -1
index += 1
if index == len(s):
return 0

final_integer = 0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なんか命名がしっくりこないです。あまりfinalをつけることによって意味が増えていないと思います。あとは、finalといいつつINTの範囲を超える場合はMAX_INT、MIN_INTが返されているなという感想を持ちました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あまり良い変数名が思いつかなかったので、問題文からそのまま取ってきてしまいました。処理の内容踏まえると、digits_integerとかが良いでしょうかね。

while index < len(s) and s[index].isdigit():
digit = ord(s[index]) - ord('0')
final_integer = 10 * final_integer + sign * digit
if final_integer > MAX_INT:
return MAX_INT
if final_integer < MIN_INT:
return MIN_INT
index += 1
return final_integer
```

### 4回目
```python
class Solution:
def myAtoi(self, s: str) -> int:
index = 0
sign = 1
MAX_INT = (1 << 31) - 1
MIN_INT = - (1 << 31)

while index < len(s) and s[index].isspace():
index += 1

if index == len(s):
return 0

if s[index] in ('+', '-'):
if s[index] == '-':
sign = -1
index += 1

if index == len(s):
return 0

digits_integer = 0
while index < len(s) and s[index].isdigit():
digit = ord(s[index]) - ord('0')
digits_integer = 10 * digits_integer + sign * digit
if digits_integer > MAX_INT:
return MAX_INT
if digits_integer < MIN_INT:
return MIN_INT
index += 1

return digits_integer
```