diff --git a/grind75_hard/06_224_Basic Calculator/level_1.py b/grind75_hard/06_224_Basic Calculator/level_1.py new file mode 100644 index 0000000..b83ab54 --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_1.py @@ -0,0 +1,39 @@ +# 数字符号も含め10進数に直して、最後に全部足し算する +# ()で囲まれた部分を先に計算するため、stackに入れておく +# 各文字に対する処理をそれぞれ記載 +class Solution: + def calculate(self, s: str) -> int: + stack = [] + sign = 1 + num = 0 + for c in s: + if c.isspace(): + continue + if c.isdigit(): + num = num * 10 + int(c) + continue + if c == "(": + stack.append((c, sign)) + sign = 1 + continue + if c == "-": + stack.append((num, sign)) + sign = -1 + if c == "+": + stack.append((num, sign)) + sign = 1 + if c == ")": + num *= sign + while 1: + expression, sign = stack.pop() + if expression == "(": + break + num += expression * sign + stack.append((num, sign)) + num = 0 + if num != 0: + stack.append((num, sign)) + result = 0 + for num, sign in stack: + result += num * sign + return result diff --git a/grind75_hard/06_224_Basic Calculator/level_2.py b/grind75_hard/06_224_Basic Calculator/level_2.py new file mode 100644 index 0000000..b8461c9 --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_2.py @@ -0,0 +1,29 @@ +# 括弧内の計算を再帰的に行う +class Solution: + def calculate(self, s: str) -> int: + def helper_calculate(index): + result = 0 + num = 0 + sign = 1 + while index < len(s): + if s[index].isdigit(): + num = num * 10 + int(s[index]) + if s[index] == "+": + result += num * sign + num = 0 + sign = 1 + if s[index] == "-": + result += num * sign + num = 0 + sign = -1 + if s[index] == ")": + result += num * sign + return index, result + if s[index] == "(": + index, result_in_brackers = helper_calculate(index + 1) + result += result_in_brackers * sign + index += 1 + result += num * sign + return result + + return helper_calculate(0) diff --git a/grind75_hard/06_224_Basic Calculator/level_3.py b/grind75_hard/06_224_Basic Calculator/level_3.py new file mode 100644 index 0000000..d93808b --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_3.py @@ -0,0 +1,28 @@ +class Solution: + def calculate(self, s: str) -> int: + def helper_calculate(index): + num = 0 + sign = 1 + result = 0 + while index < len(s): + if s[index].isdigit(): + num = 10 * num + int(s[index]) + if s[index] == "+": + result += num * sign + num = 0 + sign = 1 + if s[index] == "-": + result += num * sign + num = 0 + sign = -1 + if s[index] == ")": + result += num * sign + return result, index + if s[index] == "(": + result_in_brackets, index = helper_calculate(index + 1) + result += result_in_brackets * sign + index += 1 + result += num * sign + return result + + return helper_calculate(0) diff --git a/grind75_hard/06_224_Basic Calculator/level_4.py b/grind75_hard/06_224_Basic Calculator/level_4.py new file mode 100644 index 0000000..96df556 --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_4.py @@ -0,0 +1,38 @@ +# 再帰下降構文解析 +class Solution: + def calculate(self, s: str) -> int: + index = 0 + + def get_next_expression(): + nonlocal index + index += 1 + while index < len(s) and s[index].isspace(): + index += 1 + + def expr(): + nonlocal index + result = factor() + while index < len(s) and s[index] in "+-": + op = s[index] + get_next_expression() + if op == "+": + result += factor() + else: + result -= factor() + return result + + def factor(): + nonlocal index + result = 0 + while index < len(s) and s[index].isdigit(): + result = 10 * result + int(s[index]) + get_next_expression() + if index < len(s) and s[index] == "(": + get_next_expression() + result = expr() + get_next_expression() # ")"を読み飛ばす + return result + + if index < len(s) and s[0].isspace(): + get_next_expression() + return expr() diff --git a/grind75_hard/06_224_Basic Calculator/level_5.py b/grind75_hard/06_224_Basic Calculator/level_5.py new file mode 100644 index 0000000..543afb3 --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_5.py @@ -0,0 +1,39 @@ +# 再帰下降構文解析 +class Solution: + def calculate(self, s: str) -> int: + index = 0 + + def skip_spaces(): + nonlocal index + index += 1 + while index < len(s) and s[index].isspace(): + index += 1 + + def expr(): + nonlocal index + result = factor() + while index < len(s) and s[index] in "+-": + op = s[index] + skip_spaces() + if op == "+": + result += factor() + else: + result -= factor() + return result + + def factor(): + nonlocal index + result = 0 + if index < len(s) and s[index] == "(": + skip_spaces() + result = expr() + skip_spaces() # ")"を読み飛ばす + return result + while index < len(s) and s[index].isdigit(): + result = 10 * result + int(s[index]) + skip_spaces() + return result + + if index < len(s) and s[0].isspace(): + skip_spaces() + return expr() diff --git a/grind75_hard/06_224_Basic Calculator/level_6.py b/grind75_hard/06_224_Basic Calculator/level_6.py new file mode 100644 index 0000000..495075d --- /dev/null +++ b/grind75_hard/06_224_Basic Calculator/level_6.py @@ -0,0 +1,40 @@ +# 再帰下降構文解析 +# スペースを最初に除去 +# result = 0のタイミングを修正 +# 単行演算子を明示的に処理 +class Solution: + def calculate(self, s: str) -> int: + index = 0 + + def expr(): + nonlocal index + if index < len(s) and s[index] == "-": + index += 1 + result = -factor() + else: + result = factor() + + while index < len(s) and s[index] in "+-": + op = s[index] + index += 1 + if op == "+": + result += factor() + else: + result -= factor() + return result + + def factor(): + nonlocal index + if index < len(s) and s[index] == "(": + index += 1 + result = expr() + index += 1 # ")"を読み飛ばす + return result + result = 0 + while index < len(s) and s[index].isdigit(): + result = 10 * result + int(s[index]) + index += 1 + return result + + s = s.replace(" ", "") + return expr()