diff --git a/arai60/atoi/phase1.py b/arai60/atoi/phase1.py new file mode 100644 index 0000000..c25bb25 --- /dev/null +++ b/arai60/atoi/phase1.py @@ -0,0 +1,71 @@ +INT_MAX = 2 ** 31 -1 +INT_MIN = - 2 ** 31 +# 仮に数字の場合文字列の最初に来うるのは符号か数字のみ +# 符号が来た場合も次の文字が数字じゃなければならない +# is_number -> extract_number(integer部分を抜き取る) -> 数字化処理 + +def char_is_number(char: str)->bool: + if ord(char) >= ord("0") and ord("9") >= ord(char): + return True + return False + +def is_number(s: str)->bool: + for index, char in enumerate(s): + if char == " ": + continue + elif char == "-" or char == "+": + if index == len(s) - 1: + #符号が終端の場合 + return False + else: + #次の文字が数字かどうかで判断 + return char_is_number(s[index+1]) + elif char_is_number(char): + return True + else: + return False + return False + +def search_start_index(s: str)->int: + for index, char in enumerate(s): + if char == "+" or char == "-": + return index + elif char_is_number(char): + return index + +def extract_number(s: str)->str: + start_index = search_start_index(s) + end_index = len(s) + for index in range(start_index+1, len(s)): + if not char_is_number(s[index]): + end_index = index + break + return s[start_index:end_index] + +def string_to_integer(s: str)->int: + if not is_number(s): + return 0 + + extracted_number_string = extract_number(s) + sign = 1 + if extracted_number_string[0] == "-": + sign = -1 + extracted_number_string = extracted_number_string[1:] + elif extracted_number_string[0] == "+": + extracted_number_string = extracted_number_string[1:] + + after_atoi_number = 0 + for index, char in enumerate(extracted_number_string): + digit = len(extracted_number_string) - index - 1 + after_atoi_number += (ord(char)-ord("0")) * 10 ** digit + + return after_atoi_number * sign + + + +def clamp(number: int) -> int: + if number > INT_MAX: + return INT_MAX + elif number < INT_MIN: + return INT_MIN + return number diff --git a/arai60/atoi/phase2.py b/arai60/atoi/phase2.py new file mode 100644 index 0000000..21bba53 --- /dev/null +++ b/arai60/atoi/phase2.py @@ -0,0 +1,54 @@ +# https://github.com/cheeseNA/leetcode/pull/5/files +# まず空白に関してカーソルを動かす, そのあと符号に関してカーソルを動かし, 数字が続く限りwhileで処理をしていた。 +# 僕のphase1の解答と違いif文に関しての複雑な制御がいらなくて賢かった。(でもatoiを作れという課題なのにpythonのintを使ってるのはどうなんだろう) + +# https://github.com/usatie/leetcode/commit/9b4ea58330b31c3c1371fe242bc02ab1a9012329 +# 上のほぼC++版, 上もだがオーバーフローは最後に確認ではなく逐次確認の方が良いのだと思った +# 最後に確認する方法だと下手したらオーバーフローが二周してくる場合とかもあるなと思った + +INT_MAX = 2 ** 31 -1 +INT_MIN = - 2 ** 31 + +def char_is_number(char: str)->bool: + if ord(char) >= ord("0") and ord("9") >= ord(char): + return True + return False + +def string_to_integer(s: str)->int: + if len(s) == 0: + return 0 + + current_pointer = 0 + while current_pointer < len(s): + # 空白に関して処理をする + if s[current_pointer] != " ": + break + current_pointer += 1 + if current_pointer == len(s): + return 0 + + sign = 1 + #符号処理 + if s[current_pointer] == "+": + current_pointer += 1 + elif s[current_pointer] == "-": + sign = -1 + current_pointer += 1 + + abs_value = 0 + while current_pointer < len(s) and char_is_number(s[current_pointer]): + abs_value *= 10 + abs_value += ord(s[current_pointer]) - ord("0") + if abs_value * sign > INT_MAX: + return INT_MAX + elif abs_value * sign < INT_MIN: + return INT_MIN + current_pointer += 1 + + return abs_value * sign + + +class Solution: + def myAtoi(self, s: str) -> int: + after_atoi_number = string_to_integer(s) + return after_atoi_number \ No newline at end of file diff --git a/arai60/atoi/phase3.py b/arai60/atoi/phase3.py new file mode 100644 index 0000000..3ab68c4 --- /dev/null +++ b/arai60/atoi/phase3.py @@ -0,0 +1,44 @@ +INT_MAX = 2 ** 31 - 1 +INT_MIN = - 2 ** 31 +def char_is_number(char: str)->int: + if ord(char) >= ord("0") and ord("9") >= ord(char): + return True + return False + +def string_to_integer(s: str)->int: + if len(s) == 0: + return 0 + + current_pointer = 0 + while current_pointer < len(s): + if s[current_pointer] != " ": + break + current_pointer += 1 + + if current_pointer == len(s): + return 0 + + sign = 1 + # 符号処理 + if s[current_pointer] == "+": + current_pointer += 1 + elif s[current_pointer] == "-": + sign = -1 + current_pointer += 1 + + abs_value = 0 + while current_pointer < len(s) and char_is_number(s[current_pointer]): + abs_value *= 10 + abs_value += ord(s[current_pointer]) - ord("0") + if abs_value * sign > INT_MAX: + return INT_MAX + elif abs_value * sign < INT_MIN: + return INT_MIN + current_pointer += 1 + + return abs_value * sign + +class Solution: + def myAtoi(self, s: str) -> int: + after_atoi_number = string_to_integer(s) + return after_atoi_number \ No newline at end of file diff --git a/arai60/atoi/phase4.py b/arai60/atoi/phase4.py new file mode 100644 index 0000000..18ad7ed --- /dev/null +++ b/arai60/atoi/phase4.py @@ -0,0 +1,34 @@ +INT_MAX = 2 ** 31 - 1 +INT_MIN = - 2 ** 31 + +def char_is_number(c: str)->bool: + return ord("0") <= ord(c) <= ord("9") + +class Solution: + def myAtoi(self, s: str) -> int: + index = 0 + while index < len(s) and s[index] == " ": + index += 1 + + if index == len(s): + return 0 + + sign = 1 + if s[index] == "+": + index += 1 + elif s[index] == "-": + sign = -1 + index += 1 + + absolute_value = 0 + while index < len(s) and char_is_number(s[index]): + absolute_value *= 10 + absolute_value += ord(s[index]) - ord("0") + if absolute_value * sign > INT_MAX: + return INT_MAX + elif absolute_value * sign < INT_MIN: + return INT_MIN + index += 1 + + return absolute_value * sign + \ No newline at end of file