2019-01-31

LeetCode 27. Basic Calculator II.jpg

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)載需保留文章來源,作者信息和本聲明.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,882評(píng)論 0 38
  • 想要知道你的牌是什么?如何更愉快地和愛人相處及理解?彼此?點(diǎn)贊加我wx:Sophiannn,給你準(zhǔn)備了大禮包「每天...
    虹姐談情緒管理閱讀 374評(píng)論 1 2
  • 引言 在應(yīng)用中,當(dāng)某些業(yè)務(wù)數(shù)據(jù)量過大時(shí)會(huì)導(dǎo)致數(shù)據(jù)庫讀寫性能急劇下降甚至拖慢其它業(yè)務(wù)的情況。此時(shí)便需要對(duì)數(shù)據(jù)庫進(jìn)行不...
    PKAQ閱讀 11,298評(píng)論 16 11
  • 牽引力教育女生到底適不適合學(xué)IT 一提到編程、計(jì)算機(jī)、工程師等字眼,大家腦海里就浮現(xiàn)出「工科男」、「程序猿」等形象...
    大大大西瓜666閱讀 219評(píng)論 0 0
  • 前言 在游戲中,我們經(jīng)常想要找到從一個(gè)位置到另一個(gè)位置的路徑。我們不僅試圖找到最短的距離;我們還想考慮旅行時(shí)間。要...
    Huws閱讀 1,513評(píng)論 0 0