1. 程式人生 > >LeetCode227 Basic Calculator II 基本計算器

LeetCode227 Basic Calculator II 基本計算器

題目描述

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變數,比操作字串變數要快點吧。