Leetcode 224/227/772 计算器
题目描述 Leetcode 224
Leetcode 224:
这里想让我们实现一个基础的计算器,来计算给定的字符串。
给定的字符串中包含 (
)
+
-
和非负整数和空格。
# Example 1:
#
# Input: "1 + 1"
# Output: 2
# Example 2:
#
# Input: " 2-1 + 2 "
# Output: 3
# Example 3:
#
# Input: "(1+(4+5+2)-3)+(6+8)"
# Output: 23
注意:
- 我们可以认为给定的表达式总是有效的。
- 不要使用内置的 eval 库函数。
题目分析 Leetcode 224
刚开始做这道题时,确定了使用栈作为数据结构,但在字符串入栈时会面临两个问题:
- 输入的数字是连续的问题:比如 "123+123" 这里就需要将 123 转换成 int 再压入栈。
- 计算的顺序问题:如果按照正常的顺序入栈,在进行减法运算时就会发生问题,比如 "(7-8+9)"
- 正常的入栈结果是(/7/-/8/+/9
- 而出栈的结果是 9+8-7 与期待的结果不符。
解决思路,通过一个变量 operand 累计需要转换的操作数,将字符串反序来保证正常的计算结构。
# 224. Basic Calculator
# Implement a basic calculator to evaluate a simple expression string.
# The expression string may contain open ( and closing parentheses ),
# the plus + or minus sign -, non-negative integers and empty spaces
# Example 1:
#
# Input: "1 + 1"
# Output: 2
# Example 2:
#
# Input: " 2-1 + 2 "
# Output: 3
# Example 3:
#
# Input: "(1+(4+5+2)-3)+(6+8)"
# Output: 23
# Note:
# You may assume that the given expression is always valid.
# Do not use the eval built-in library function.
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
stack = []
operand, n = 0, 1
# Reverse string
for index in range(len(s)-1, -1, -1):
char = s[index]
if char == " ":
continue
if char.isdigit():
# transform number string to number
# like "123" to 3+20+100=123
operand = operand + int(char) * n
n = n * 10
else:
# put before formatted string to the stack
if n != 1:
stack.append(operand)
n, operand = 1, 0
# due to the reversed order, '(' represents the end
if char == '(':
self.eval(stack)
# put current char to the stack like '+', '+', '-'
else:
stack.append(char)
if n != 1:
stack.append(operand)
return self.eval(stack)
def eval(self, stack):
result = stack.pop()
while stack:
sign = stack.pop()
if sign == "+":
operand = stack.pop()
result = result + operand
elif sign == "-":
operand = stack.pop()
result = result - operand
elif sign == ")":
break
stack.append(result)
return result
题目描述 Leetcode 227
这次规定的字符串包含了 *
/
符号,但缺少了 ( ) 的优先级。
# Input: "3+2*2"
# Output: 7
# Example 2:
# Input: " 3/2 "
# Output: 1
# Example 3:
# Input: " 3+5 / 2 "
# Output: 5
题目分析 Leetcode 227
这次换了一个解决思路,可以把给定的字符串中加减运算都看成相加运算,当遇到 -
时,入栈的结果是当前操作数的相反数。当遇到乘法和除法时,将栈顶元素取出进行运算后再放回栈顶。
具体解决时,可以使用 pre_sign 作为变量保存当前数组的正负,比如 "5-6" 可以看成 "+5" + "-6",加减表示当前符合的正负。
class Solution1:
def calculate(self, s):
index = 0
stack = []
operand = 0
pre_sign = "+"
while index < len(s):
char = s[index]
if char == "":
continue
if char.isdigit():
operand = 10 * operand + int(char)
if char in ['+', '-', '*', '/'] or index == len(s)-1:
if pre_sign == '+':
stack.append(operand)
elif pre_sign == "-":
stack.append(-operand)
elif pre_sign == "*":
stack.append(stack.pop() * operand)
elif pre_sign == "/":
stack.append(int(stack.pop() / operand))
pre_sign = char
operand = 0
index += 1
return sum(stack)
题目描述 Leetcode 772
在上题的基础上增加了 (
)
的运算。
# "1 + 1" = 2
# " 6-4 / 2 " = 4
# "2*(5+5*2)/3+(6/2+8)" = 21
# "(2+6* 3+5- (3*14/7+2)*5)+3"=-12
题目分析 Leetcode 772
这题其实上上两题的综合,由于在括号内的计算和外部一致,所以这里考虑使用递归来实现,将括号内计算的结果放入到栈中。但这里需要考虑到一个小问题,就是在进行递归运算时,由于括号内的字符串已经被计算过了,所以需要返回括号内的字符串的长度,用于忽略这些字符的计算。
class Solution2:
def calculate(self, s):
index = 0
stack = []
operand = 0
pre_sign = "+"
while index < len(s):
char = s[index]
if char == "":
continue
if char.isdigit():
operand = 10 * operand + int(char)
if char in ['+', '-', '*', '/', '(', ')'] or index == len(s)-1:
if char == "(":
operand, lenth = self.calculate(s[index+1:])
index = index + lenth
if pre_sign == '+':
stack.append(operand)
elif pre_sign == "-":
stack.append(-operand)
elif pre_sign == "*":
stack.append(stack.pop() * operand)
elif pre_sign == "/":
stack.append(int(stack.pop() / operand))
if char == ")":
return sum(stack), index+1
pre_sign = char
operand = 0
index += 1
return sum(stack)
Leetcode 224/227/772 计算器的更多相关文章
- LeetCode 227. 基本计算器 II(Basic Calculator II)
227. 基本计算器 II 227. Basic Calculator II 题目描述 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式仅包含非负整数,+,-,*,/ 四种运算符和 ...
- Java实现 LeetCode 227 基本计算器 II(二)
227. 基本计算器 II 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 . 整数除法仅保留整数部分. 示例 1: 输入: ...
- 【LeetCode】227. Basic Calculator II 解题报告(Python)
[LeetCode]227. Basic Calculator II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: h ...
- [LeetCode] 224. Basic Calculator 基本计算器
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- leetcode 224. Basic Calculator 、227. Basic Calculator II
这种题都要设置一个符号位的变量 224. Basic Calculator 设置数值和符号两个变量,遇到左括号将数值和符号加进栈中 class Solution { public: int calcu ...
- [LeetCode] 227. 基本计算器 II
题目链接: https://leetcode-cn.com/problems/basic-calculator-ii 难度:中等 通过率:33.2% 题目描述: 实现一个基本的计算器来计算一个简单的字 ...
- Java实现 LeetCode 224 基本计算器
224. 基本计算器 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 . 示例 1: 输入: "1 ...
- Leetcode 227.基本计算器II
基本计算器II 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 . 整数除法仅保留整数部分. 示例 1: 输入: " ...
- Leetcode 224.基本计算器
基本计算器 实现一个基本的计算器来计算一个简单的字符串表达式的值. 字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 . 示例 1: 输入: "1 + 1 ...
随机推荐
- 强大的捉包工具Fiddler
Fiddler2出现 creation of the root certificate was not successful 错误 http://www.zhaokeli.com/Article/63 ...
- [bzoj 5143][Ynoi 2018]五彩斑斓的世界
传送门 Descroption 给了你一个长为n的序列a,有m次操作 1.把区间[l,r]中大于x的数减去x 2.查询区间[l,r]中x的出现次数 Solution 分块 对于每个块,我们都分别维护: ...
- codeforces#1120C. Compress String(dp+后缀自动机)
题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一 ...
- Linux - /bin/sh^M: bad interpreter: No such file or directory
问题 在Windows环境下用Notepad++写了个shell脚本,上传到Linux平台后运行报错如下: /bin/sh^M: bad interpreter: No such file or di ...
- [APIO2018]铁人两项——圆方树+树形DP
题目链接: [APIO2018]铁人两项 对于点双连通分量有一个性质:在同一个点双里的三个点$a,b,c$,一定存在一条从$a$到$c$的路径经过$b$且经过的点只被经过一次. 那么我们建出原图的圆方 ...
- [转载]virtual topology虚拟拓扑
原文地址:topology虚拟拓扑">virtual topology虚拟拓扑作者:一丝尘埃 topology虚拟拓扑" title="[转载]virtual to ...
- jquery报变量没定义错误的原因
该变量定义的范围:不在使用的方法中:
- DES算法实现
概述(团队项目) DES是一个分组加密算法,它以64位为分组对数据加密.同时DES也是一个对称算法:加密和解密用的是同一个算法.DES是一个包含16个阶段的"替换–置换"的分组加密 ...
- Eclipse插件(导出UML图,打开文件资源管理器插件,静态代码分析工具PMD,在eclipse上安装插件)
目录 能够导出UML图的Eclipse插件 打开文件资源管理器插件 Java静态代码分析工具PMD 如何在eclipse上安装插件 JProfiler性能分析工具 从更新站点安装EclEmma 能够导 ...
- sublime的一些常用快捷键总结
下面是四种快捷键类型: 1.编辑类 Ctrl+J 合并选中的多行代码为一行.举个例子:将多行格式的CSS属性合并为一行.Ctrl+Shift+D 复制光标所在整行,插入到下一行.Tab 向右缩进.Sh ...