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.

描述

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: "3+2*2"
输出: 7
示例 2:

输入: " 3/2 "
输出: 1
示例 3:

输入: " 3+5 / 2 "
输出: 5
说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

思路

  • 我们使用两个栈来实现表达式求值.
  • 其中一个用来存储数字,另一个来存储符号.
  • 我们从给定的字符串中不断的取出数字和符号,若是数字,我们将其压入数字栈,如果是符号,我们和当前栈顶的符号进行比较,如果当前符号的优先级小于等于栈顶元素的符号,我们弹出符号栈顶元素,并用此符号对数字栈栈顶的两个元素进行运算,并将运算的结果重新压入数字栈,直到当前符号大于符号栈栈顶元素或者符号栈为空.
# -*- 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
        """
        # 声明两个栈,用于存储数字和操作符
        stack1, stack2 = [], []
        # num用于从字符串中取出数字
        num = 0
        for item in s:
            # 取数字
            if item.isdigit():
                num = num * 10 + ord(item) - ord("0")
            # 如果为空则继续执行
            elif item == " ":
                continue
            else:
                # 向数字栈中添加数字
                stack1.append(num)
                # 数字重置为0
                num = 0
                # 如果符号栈为空,将当前符号压入栈
                if not stack2:
                    stack2.append(item)
                else:
                    # 如果当前操作符优先级小于等于符号栈栈顶操作符,我们持续进行运算
                    while stack2 and self.compare(stack2[-1], item):
                        # 从数字栈中取出两个数字
                        num1, num2 = stack1.pop(), stack1.pop()
                        # 对这两个数字进行当前符号的运算,并将运算结果压入数字栈
                        stack1.append(self.operate(stack2.pop(), num2, num1))
                    # 将当前符号压入符号栈
                    stack2.append(item)
        # 将最后剩下的数字压入数子栈
        stack1.append(num)
        # 对剩下的数字和符号进行运算
        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):
        # 运算函数
        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的优先级>=op1的优先级返回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

源代码文件在这里.
©本文首发于何睿的博客,欢迎转载,转载需保留文章来源,作者信息和本声明.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,748评论 0 38
  • 想要知道你的牌是什么?如何更愉快地和爱人相处及理解️彼此?点赞加我wx:Sophiannn,给你准备了大礼包「每天...
    虹姐谈情绪管理阅读 2,870评论 1 2
  • 引言 在应用中,当某些业务数据量过大时会导致数据库读写性能急剧下降甚至拖慢其它业务的情况。此时便需要对数据库进行不...
    PKAQ阅读 13,876评论 16 11
  • 牵引力教育女生到底适不适合学IT 一提到编程、计算机、工程师等字眼,大家脑海里就浮现出「工科男」、「程序猿」等形象...
    大大大西瓜666阅读 1,540评论 0 0
  • 前言 在游戏中,我们经常想要找到从一个位置到另一个位置的路径。我们不仅试图找到最短的距离;我们还想考虑旅行时间。要...
    Huws阅读 5,410评论 0 0