coding: 计算器的实现

224 阅读2分钟

coding: 计算器的实现

题目

实现一个基本的计算器来计算一个简单的字符串表达式的值。 字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。

示例 1:

输入: "1 + 1"
输出: 2

示例 2:

输入: "2-1 + 2 "
输出: 3

示例 3:

输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23

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

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/basic-calculator

题解

思想

  1. 逆波兰表达式——中缀表达式转后缀表达式

  2. 栈实现后缀表达式的计算

算法

关于逆波兰表达式和后缀表达式的计算:

点击:链接

代码

//计算器
    public int calculate(String s) {
        //求逆波兰表达式
        ArrayList<Object> array= new ArrayList<>();
        Stack<Object> stack=new Stack<>();
        int num=0;
        int n=0;
        char c;
        for(int i=0;i<s.length();i++){
            c=s.charAt(i);
            //求出每个值
            if (Character.isDigit(c)){
                while (i<s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'){
                    num=num*10+(c-'0');
                    i++;
                    if (i<s.length()) {
                        c = s.charAt(i);
                    }
                }
                array.add(num);
                num=0;
                i--;
                //不为数值、且不为空时
            }else if (c!=' '){
                if (c==')'){    //‘)’,直接出栈,直到弹出'('
                    while ((char)stack.peek()!='('){
                        array.add(stack.pop());
                    }
                    stack.pop();
                }else{
                    if (c=='(' || stack.isEmpty() || (char)stack.peek()=='('){    //‘(’或栈为空时,直接入栈
                        stack.add(c);
                    }
                    else if ((c=='*' || c=='/') && ((char)stack.peek()=='+' ||(char)stack.peek()=='+')){
                        stack.add(c);       //优先级大于栈顶元素时直接入栈
                    }else {
                        array.add(stack.pop()); //其他情况下,栈顶元素出栈并入队,c再入栈
                        stack.add(c);
                    }
                }
            }
        }
        while (!stack.isEmpty()){   //栈中所有元素入队
            array.add(stack.pop());
        }

        //h后缀表达式求和a
        Object num1,num2;
        for (Object o : array) {
            switch (o + "") {   //将object转为字符串进行判断(数值还是操作符)
                case "+": {     //是操作符时,弹入两个元素计算,将结果入栈
                    num1 = stack.pop();
                    num2 = stack.pop();
                    stack.add(Integer.sum((int)num1, (int)num2));
                    break;
                }
                case "-": {
                    num1 = stack.pop();
                    num2 = stack.pop();
                    stack.add((int)num2 - (int)num1);    //这里要注意数值顺序
                    break;
                }
                case "*": {
                    num1 = stack.pop();
                    num2 = stack.pop();
                    stack.add((int)num2 * (int)num1);
                    break;
                }
                case "/": {
                    num1 = stack.pop();
                    num2 = stack.pop();
                    stack.add((int)num2 / (int)num1);    //这里要注意数值顺序
                    break;
                }
                default: {
                    stack.push(o);   //是数值时,进栈
                }
            }
        }
        return (int)stack.pop();
    }