-
Notifications
You must be signed in to change notification settings - Fork 0
Solved Arai60/8. String to Integer (atoi) #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| next_digit = sign * (ord(s[index]) - ord('0')) | ||
| if num > (MAX_INT - next_digit) // 10: | ||
| return MAX_INT | ||
| if num < (MIN_INT - next_digit) // 10 + 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if num <= (MIN_INT - next_digit) // 10:でも動きますかね?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
そうですね。ただ、自分の意図としては上と同じように超えた時に丸めるという意味合いが重要と思っているのでこうしてます
| ```python | ||
| class Solution: | ||
| def myAtoi(self, s: str) -> int: | ||
| index = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if s is None:
return 0Noneの時の処理を入れたくなりました
| def ch_to_i(ch: str) -> int: | ||
| return ord(ch) - ord('0') | ||
|
|
||
| self.index = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
インスタンス変数を変更すると、複数のスレッドで同時にこの関数を読んだときに競合状態が起こると思います。現実的なコストで避けられる場合は、避けたほうが無難だと思います。
| def ch_to_i(ch: str) -> int: | ||
| return ord(ch) - ord('0') | ||
|
|
||
| self.index = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ステートマシン風に書きたかったのかなと思いました。以下のような書き方もあります。
import enum
class State(enum.Enum):
WHITESPACE = 1
SIGN = 2
ZERO = 3
INT = 4
END = 5
MAX_INT = (1 << 31) - 1
MIN_INT = -(1 << 31)
class Solution:
def myAtoi(self, s: str) -> int:
def parse_whitespace(index: int) -> tuple[State, int]:
if s[index] == ' ':
return State.WHITESPACE, index + 1
return State.SIGN, index
def parse_sign(index: int) -> tuple[State, int, int]:
if s[index] == '+':
return State.ZERO, index + 1, 1
if s[index] == '-':
return State.ZERO, index + 1, -1
return State.ZERO, index, 1
def parse_zero(index) -> tuple[State, int]:
if s[index] == '0':
return State.ZERO, index + 1
if s[index] in string.digits:
return State.INT, index
return State.END, len(s)
def parse_int(index, sign, num) -> tuple[State, int, int]:
if s[index] not in string.digits:
return State.END, len(s), num
if num > (MAX_INT - ch_to_i(s[index])) // 10:
return State.END, len(s), MAX_INT
if num < (MIN_INT + ch_to_i(s[index])) // 10 + 1:
return State.END, len(s), MIN_INT
return State.INT, index + 1, num * 10 + sign * ch_to_i(s[index])
def ch_to_i(ch: str) -> int:
return ord(ch) - ord('0')
index = 0
state = State.WHITESPACE
sign = 1
num = 0
while index < len(s):
match state:
case State.WHITESPACE:
state, index = parse_whitespace(index)
case State.SIGN:
state, index, sign = parse_sign(index)
case State.ZERO:
state, index = parse_zero(index)
case State.INT:
state, index, num = parse_int(index, sign, num)
case State.END:
break
return numThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確かにこういう書き方もありですね。
参考になります
|
|
||
| while index < len(s): | ||
| if s[index] in NUMBERS: | ||
| if sign == POSITIVE and (MAX_INT - int(s[index])) // 10 - num < 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python では int は多倍長整数で実装されているため、 32/64-bit のオーバーフローしません。そのため、計算してから範囲を超えたかどうかを判定しても大丈夫です。そのほうがコードがシンプルになると思います。
num = num * 10 + int(s[index])
if sign == POSITIVE and MAX_INT < num:
return MAX_INT
if sign == NEGATIVE and -num < MIN_INT:
return MIN_INT
index += 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
もちろん承知の上ですが、その処理をして欲しい問題なのかなと思って書きました
(MAX_INTの定義で越えてるという話はありそうですが)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
他の(オーバーフローが)問題になるような言語だと、標準ライブラリーにそういう関数があることが多いというのも意識してもいいかもしれません。
まあ、要は自分で作らないべきものであるということです。
| index = 0 | ||
| while index < len(s): | ||
| if s[index] != ' ': | ||
| break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while index < len(s) and s[index] == ' ':としてもいいと思いました。
問題文:https://leetcode.com/problems/string-to-integer-atoi/description/