1. 程式人生 > >演算法50----基本計算器【棧】

演算法50----基本計算器【棧】

一、題目:基本計算器【只有 + ,- ,以及括號】

實現一個基本的計算器來計算一個簡單的字串表示式的值。

字串表示式可以包含左括號 ( ,右括號 ),加號 + ,減號 -非負整數和空格  

示例 1:

輸入: "1 + 1"
輸出: 2

示例 2:

輸入: " 2-1 + 2 "
輸出: 3

示例 3:

輸入: "(1+(4+5+2)-3)+(6+8)"
輸出: 23

非遞迴思路:

棧:

採用棧儲存遇到 ( 之前的結果。

遇到 ),將棧中最後一個數彈出計算結果。

處理過程:

res記錄結果,stack用來存結果【遇到()先存前面的結果】,sign記錄符號+、-

  1. 遇到 + :sign = 1
  2. 遇到 - :sign = -1
  3. 遇到數字:【考慮‘42’兩個字母一起的情況,採用迴圈】結果 res  += int (42) * sign
  4. 遇到 ’( ’:stack中加入 res和sign
  5. 遇到‘ ) ‘:stack彈出最後一個元素和倒數第二個元素來更新res

程式碼:

    def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            
return 0 #stack儲存遇到括號(之前的計算結果res #temp記錄數字,【如‘42’兩個數字一起出現的情況】 #sign記錄符號+,- #res記錄計算結果 stack,temp = [],'' sign , res , i = 1 , 0 , 0 while i < len(s): #遇到字母:如果有兩個數字同時出現,採用迴圈解決 #res結果把符號相乘 if s[i].isdigit(): while i<len(s) and s[i].isdigit(): temp
+= s[i] i += 1 i -= 1 res += int(temp)*sign #遇到+,-,sign=1,-1 elif s[i] == '+': sign = 1 elif s[i] == '-': sign = -1 #遇到(,將前面的res和符號sign存入棧中,初始化res和sign elif s[i] == '(': stack.append(res) stack.append(sign) res,sign = 0,1 #遇到),將棧中原來的結果res和符號sign彈出和當前的res更新得到新的結果res elif s[i] == ')': if stack: sign_tmp = stack.pop() res_tmp = stack.pop() res = res_tmp + res*sign_tmp i += 1 temp= '' return res

二、題目:基本計算器二【只有加減乘除,沒有括號】

實現一個基本的計算器來計算一個簡單的字串表示式的值。

字串表示式僅包含非負整數,+-*/ 四種運算子和空格  。 整數除法僅保留整數部分。

示例 1:

輸入: "3+2*2"
輸出: 7

示例 2:

輸入: " 3/2 "
輸出: 1

示例 3:

輸入: " 3+5 / 2 "
輸出: 5

非遞迴思路:

棧:

  • 遇到數字:就將數字存入棧中。【考慮兩個數字一起出現的情況】
  • 遇到 * 或 / 就將乘或者除計算結束再存入棧中。【其中還要考慮是數字的情況】
    • 將棧最後一個元素彈出,然後與 【乘號或者除號後面一個元素的數字】進行計算得到新的結果再存進棧中
  • 遇到加減,sign = 1或-1

結果:

將棧中所有元素加總就可以了

def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return 0
        # return eval(s)
        stack = []
        res,sign,i= 0,1,0
        num = ''
        ca = True
        while i < len(s):
            ss = s[i]
#數字,考慮兩個數字出現的情況,用迴圈
            if ss.isdigit():
                while i<len(s) and s[i].isdigit():
                    num += s[i]
                    i += 1
                    ca = False
                stack.append(int(num)*sign)
#加減sign = 1或者-1
            elif ss == '+':
                sign = 1
            elif ss == '-':
                sign = -1
#乘號,
            elif ss == '*':
                #可能後面是空白符號
                while not s[i].isdigit():
                    i += 1
                #考慮兩個數字一起出現
                while i<len(s) and s[i].isdigit():
                    num += s[i]
                    i += 1
                    ca = False
                #將棧最後一個元素和乘號*後面一個數字相乘
                res = stack.pop() * int(num)
                #將結果存入棧中
                stack.append(res)
#除號
            elif ss == '/':
                value = stack.pop()
                while not s[i].isdigit():
                    i += 1
                while i<len(s) and s[i].isdigit():
                    num += s[i]
                    i += 1
                    ca = False
                #m是用來限制除法取整的,如果除的結果是負數,則結果要加1,正數不用
                m = value//int(num)
                if value % int(num) != 0:
                    m += 1 if m < 0 else 0
                #將除的結果加入棧中
                res = int(m)
                stack.append(res)
            if ca:
                i += 1
            num , ca = '',True
        return sum(stack)