class Solution:
def calculate(self, s: str) -> int:
# 初始化sign为 “+”,是因为开头是数字
num ,stack ,sign = 0 , [] , '+'
for i in range(len(s)):
ch = s[i]
if ch.isdigit():
num = num * 10 + int(ch)
#根据当前数字之前的符号,来决定如何处理当前数值
# 并将处理后的数值压入栈中
if ch in "+-*/" or i == len(s)-1:
if sign == "+" :
stack.append(num)
elif sign == "-" :
stack.append(-num)
elif sign == "*":
stack.append(stack.pop() * num)
else:
stack.append(int(stack.pop()/num))
num = 0
sign = ch
return sum(stack)
- トピック分析
- 小学校の知識から、基本的な計算では、まず乗算と除算を行い、次に加算と減算を行うことがわかります。括弧がある場合は、最初に括弧内の値を計算します。
- このトピックでは括弧がないため、最初に乗算と除算を計算し、次に加算と減算を計算します。
- 基本的に、この問題を解決するには、スタックのデータ構造を使用する必要があります。スタックを初期化し、シンボルを初期化します。最初のシンボルはすべてプラス記号です。
- 数値の場合は、最初に文字列を整数に計算します
- 現在の文字列が文字の場合、加算と減算の場合は、numにその係数を掛けてから、スタックにプッシュします。乗算と除算の場合は、最初にスタックをポップアウトして、現在の要素に対して操作を実行します。そしてそれをスタックにプッシュします
- 次に、現在の数値を0に更新し、現在の係数を記録します
- 要約する
- テストポイントの1つは、文字列を10進整数に変換する方法です。
- テストセンター2、「+-* /」に遭遇したときに何をすべきか
- テストポイント3、各計算後に現在の係数と次の整数を更新する方法
class Solution:
def calculate(self, s: str) -> int:
sDeque = deque(s)
def helper(sDeque):
num = 0
sign = "+"
stack = []
while len(sDeque) > 0:
# 注意 这里需要从头部开始pop
char = sDeque.popleft()
if char.isdigit():
num = num * 10 + int(char)
if char == '(':
#遇到左括号,开始递归调用
num = helper(sDeque)
if (not char.isdigit() and char != " ") or len(sDeque) == 0:
if sign == "+":
stack.append(num)
elif sign == "-":
stack.append(-num)
elif sign =='*':
stack.append(stack.pop()*num)
elif sign == '/':
stack.append(stack.pop()/num)
# 重置num和sign
num = 0
sign = char
if char == ")":
#遇到右括号直接结束当前的递归
break
return sum(stack)
return helper(sDeque)
- トピック分析
- これは前のトピックのアップグレードバージョンであり、角かっこが追加されています。
- 最初に前の文字列を両端キューに変換します
- その他は変更されません。左括弧が見つかった場合は、再帰的に計算を実行する必要があります。この再帰呼び出しを終了するために右括弧が見つかった場合は、whileループからジャンプしてください。
複雑な問題を解体する方法についての投稿があります。電卓を実装するには、labuladongは間違いなく大物であり、このトピックの説明は非常に明確です。
要約:スタックは非常に単純だと思いましたが、特定の問題を適用する場合、データ構造が単純であるほど単純ではないことがわかりました。