227. 基本计算器 II

题目描述

实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

示例 1:

输入: “3+2*2”
输出: 7
示例 2:

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

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

思路分析

1.将中缀表达式转为后缀表达式
2.计算后缀表达式

中缀表达式转后缀表达式方法:

  • 设置一个栈operators存储运算符
  • 逐个读取字符串的内容,如果是数字,直接输出到后缀表达式中;如果是运算符:先比较栈顶运算符和当前读取的运算符优先级,如果栈为空,直接将运算符入栈;如果栈顶运算符优先级 >= 当前运算符优先级,则将当前栈顶元素输出到后缀表达式中,重复该操作,直至栈空或栈顶运算符优先级 < 当前运算符优先级。

注意:操作数不一定只占一个字符

后缀表达式计算方法:

  • 设置一个栈operands存储操作数,依次读取后缀表达式的内容
  • 如果是操作数,则将它放入栈中;如果是操作符,从栈中提取两个操作数,按照先后记为num2, num1(先取的是num2)然后进行运算num1 optr num2,将结果压回栈中。

代码

class Solution {
    public static int calculate(String s) {
        Stack<Integer> operands = new Stack<>();
        List<String> postfix = infixToPostfix(s);
        for(String e: postfix){
            if(Character.isDigit(e.charAt(0)))
                operands.push(Integer.parseInt(e));
            else{
                int num2 = operands.pop(), num1 = operands.pop();
                int res = calculate(num1, num2, e);
                operands.push(res);
            }
        }
        return operands.pop();
    }
    private static int calculate(int num1, int num2, String operator){
        int res = 0;
        switch (operator){
            case "+": res = num1 + num2;break;
            case "-": res = num1 - num2;break;
            case "*": res = num1 * num2;break;
            case "/": res = num1 / num2;break;
        }
        return res;
    }
    private static List<String> infixToPostfix(String s){
        Stack<Character> operators = new Stack<>();
        List<String> postfix = new ArrayList<>();
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if(c == ' ')
                continue;
            if(Character.isDigit(c)){
                String num = getNum(s, i);
                postfix.add(num);
                while(i + 1 < s.length() && Character.isDigit(s.charAt(i + 1)))
                    i++;
            }
            else{
                while(!operators.isEmpty() && comparePriority(c, operators.peek()) <= 0) //栈顶运算符优先级大于等于当前运算符
                    postfix.add(operators.pop() + "");
                operators.push(c);
            }
        }
        while(!operators.isEmpty())
            postfix.add(operators.pop() + "");
        return postfix;
    }
    private static String getNum(String s, int startOfNum){
        int endOfNum = startOfNum + 1;
        while(endOfNum < s.length()){
            char c = s.charAt(endOfNum);
            if(!Character.isDigit(c))
                break;
            endOfNum++;
        }
        String num = s.substring(startOfNum, endOfNum);
        return num;
    }
    private static int comparePriority(char optr1, char optr2){
        if(optr1 == '*' || optr1 =='/'){
            if(optr2 == '*' || optr2 =='/')
                return 0;
            else return 1;
        }else{
            if(optr2 == '*' || optr2 =='/')
                return -1;
            else return 0;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值