LeetCode227 Basic Calculator II 基本計算器
阿新 • • 發佈:2018-12-11
題目描述
Basic Calculator II 給定一些非負整數和符號+, -, *, /,的組合,中間還有可能有空格。注意整數除法的截斷應該往0的方向截斷,比如3.5為3,-3.5為-3. 樣例輸入輸出: Input: “3+2*2” Output: 7
Input: " 3/2 " Output: 1
Input: " 3+5 / 2 "
Output: 5
注意:
給定的表示式都是合法的。
不可以使用內建函式eval
。
思路
每當掃描到空格時,continue。 每當掃描到數字,那麼就讓存數字的中間變數字串temp累加當前字元(要用temp時,就使用intv=int(temp)再取出來)。 每當掃描到一個運算子,那麼上一次被掃描的運算子為sign(注意是上一次)。
- 如果sign是+,那麼將intv入棧
- 如果sign是-,那麼就-intv入棧
- 如果sign是*,那麼就將出棧元素乘以intv,再入棧
- 如果sign是/,那麼就將出棧元素除以intv,再入棧(注意取整方向)
注意需要在迴圈外,再處理一下最後一個數字和最後一個運算子。 注意特殊情況,表示式只有一個數字,沒有符號。
最後,將棧內元素求和,就是結果。
程式碼
import math
class Solution:
def calculate(self, s):
stack = []
sign = ''
temp = ''
for i in range(len(s)):
if s[i] == ' ':
continue
if(s[i].isdigit()):#為數字
temp += s[i]
else:#當前為符號時,處理上一個符號
intv = int(temp)
if sign == '':#第一次讀到符號
stack.append(intv)#入棧
else:
if sign == '+':
stack.append(intv)
elif sign == '-':
stack.append(-intv)
elif sign == '*':
pop = stack.pop()
stack.append(pop*intv)
elif sign == '/':
pop = stack.pop()
stack.append(int(pop/intv))
sign = s[i]#更新為當前符號
temp = ''
#處理最後一個數字,程式碼是複製上面來的
intv = int(temp)
if sign == '+':
stack.append(intv)
elif sign == '-':
stack.append(-intv)
elif sign == '*':
pop = stack.pop()
stack.append(pop*intv)
elif sign == '/':
pop = stack.pop()
stack.append(int(pop/intv))
elif sign == '':#如果表示式只有一個數字,沒有符號
return intv
return sum(stack)
多次提交,執行時間不一定,最快時100ms。總結一下就是,每當掃描到運算子,就處理上一個運算子。如果是乘或者除,還需要出棧運算後再入棧,不然就是直接入棧(注意負號)。
Python3最快程式碼
class Solution:
def calculate(self, s):
s += '+'#這樣就不用單獨處理最後一個數字了
n = 0
sign = '+'#也處理了特殊情況,只有一個數字沒有運算子
stk = []
for c in s:
if c.isdigit():
n = 10 * n + ord(c) - 48
elif c != ' ':
if sign == '+':
stk.append(n)
elif sign == '-':
stk.append(-n)
elif sign == '*':
stk.append(stk.pop() * n)
elif sign == '/':
stk.append(int(stk.pop() / n))
sign = c
n = 0
return sum(stk)
執行時間68ms。此程式碼有兩個優點,我已經在註釋裡說了。
程式碼思想與我的基本一樣,速度方面可能跟這句n = 10 * n + ord(c) - 48
有關,也許直接操作int變數,比操作字串變數要快點吧。