LeetCode 27. Basic Calculator II
Description
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.
Example 1:
Input: "3+2*2"
Output: 7
Example 2:
Input: " 3/2 "
Output: 1
Example 3:
Input: " 3+5 / 2 "
Output: 5
Note:
You may assume that the given expression is always valid.
Do not use the eval built-in library function.
描述
實(shí)現(xiàn)一個(gè)基本的計(jì)算器來計(jì)算一個(gè)簡(jiǎn)單的字符串表達(dá)式的值。
字符串表達(dá)式僅包含非負(fù)整數(shù),+, - ,*,/ 四種運(yùn)算符和空格 。 整數(shù)除法僅保留整數(shù)部分。
示例 1:
輸入: "3+2*2"
輸出: 7
示例 2:
輸入: " 3/2 "
輸出: 1
示例 3:
輸入: " 3+5 / 2 "
輸出: 5
說明:
你可以假設(shè)所給定的表達(dá)式都是有效的。
請(qǐng)不要使用內(nèi)置的庫函數(shù) eval。
思路
- 我們使用兩個(gè)棧來實(shí)現(xiàn)表達(dá)式求值.
- 其中一個(gè)用來存儲(chǔ)數(shù)字,另一個(gè)來存儲(chǔ)符號(hào).
- 我們從給定的字符串中不斷的取出數(shù)字和符號(hào),若是數(shù)字,我們將其壓入數(shù)字棧,如果是符號(hào),我們和當(dāng)前棧頂?shù)姆?hào)進(jìn)行比較,如果當(dāng)前符號(hào)的優(yōu)先級(jí)小于等于棧頂元素的符號(hào),我們彈出符號(hào)棧頂元素,并用此符號(hào)對(duì)數(shù)字棧棧頂?shù)膬蓚€(gè)元素進(jìn)行運(yùn)算,并將運(yùn)算的結(jié)果重新壓入數(shù)字棧,直到當(dāng)前符號(hào)大于符號(hào)棧棧頂元素或者符號(hào)棧為空.
# -*- coding: utf-8 -*-
# @Author: 何睿
# @Create Date: 2019-01-28 20:41:10
# @Last Modified by: 何睿
# @Last Modified time: 2019-01-28 21:28:48
class Solution:
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
# 聲明兩個(gè)棧,用于存儲(chǔ)數(shù)字和操作符
stack1, stack2 = [], []
# num用于從字符串中取出數(shù)字
num = 0
for item in s:
# 取數(shù)字
if item.isdigit():
num = num * 10 + ord(item) - ord("0")
# 如果為空則繼續(xù)執(zhí)行
elif item == " ":
continue
else:
# 向數(shù)字棧中添加數(shù)字
stack1.append(num)
# 數(shù)字重置為0
num = 0
# 如果符號(hào)棧為空,將當(dāng)前符號(hào)壓入棧
if not stack2:
stack2.append(item)
else:
# 如果當(dāng)前操作符優(yōu)先級(jí)小于等于符號(hào)棧棧頂操作符,我們持續(xù)進(jìn)行運(yùn)算
while stack2 and self.compare(stack2[-1], item):
# 從數(shù)字棧中取出兩個(gè)數(shù)字
num1, num2 = stack1.pop(), stack1.pop()
# 對(duì)這兩個(gè)數(shù)字進(jìn)行當(dāng)前符號(hào)的運(yùn)算,并將運(yùn)算結(jié)果壓入數(shù)字棧
stack1.append(self.operate(stack2.pop(), num2, num1))
# 將當(dāng)前符號(hào)壓入符號(hào)棧
stack2.append(item)
# 將最后剩下的數(shù)字壓入數(shù)子棧
stack1.append(num)
# 對(duì)剩下的數(shù)字和符號(hào)進(jìn)行運(yùn)算
while stack2 and stack1:
num1, num2 = stack1.pop(), stack1.pop()
stack1.append(self.operate(stack2.pop(), num2, num1))
return stack1.pop()
def operate(self, operator, num1, num2):
# 運(yùn)算函數(shù)
if operator == "+": return num1 + num2
if operator == "-": return num1 - num2
if operator == "*": return num1 * num2
if operator == "/": return num1 // num2
def compare(self, op1, op2):
# op2的優(yōu)先級(jí)>=op1的優(yōu)先級(jí)返回True
# 否則返回False
if (op1 == "+" or op1 == "-") and (op2 == '+' or op2 == "-"):
return True
if (op1 == "*" or op1 == "/") and (op2 == '*' or op2 == '/'):
return True
if (op1 == "*" or op1 == "/") and (op2 == '+' or op2 == "-"):
return True
return False
源代碼文件在這里.
?本文首發(fā)于何睿的博客,歡迎轉(zhuǎn)載,轉(zhuǎn)載需保留文章來源,作者信息和本聲明.