算法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)                    

猜你喜欢

转载自www.cnblogs.com/Lee-yl/p/9959580.html