zoukankan      html  css  js  c++  java
  • 224.基本计算器

    224.基本计算器

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

    字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。

    import java.util.Stack;
    
    public class _224_基本计算器1 {
        public int calculate(String s) {
            Stack<Integer> stack1 = new Stack<>();//stack1中最多存储3个值
            Stack<Character> stack2 = new Stack<>();// stack2中最多存储2个运算符
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c == '(') { // (
                    stack2.push(c);
                } else if (c == ')') { // )
                    while (stack2.peek() != '(') {
                        char label = stack2.peek();
                        reversePolish(label,stack1);
                        stack2.pop();
                    }
                    stack2.pop();
    
                } else if (Character.isDigit(c)) { // 数字
                    add(stack1,c,s,i);
                } else {
                    if (c != ' ') {// + - * /
                        if (stack2.isEmpty()) {
                            stack2.push(c);
                        }
                        else if (stack2.peek() == '(') {
                            stack2.push(c);
                        } else if ((stack2.peek() == '+' || stack2.peek() == '-') && (c == '*' || c=='/') ) {
                            stack2.push(c);
                        } else {
                            char lable = stack2.peek();
                            reversePolish(lable,stack1);
                            stack2.pop();
                            stack2.push(c);
                        }
                    }
                }
            }
            while (!stack2.isEmpty()) {
                char label = stack2.peek();
                reversePolish(label,stack1);
                stack2.pop();
            }
    
            return stack1.pop();
        }
        // 计算逆波兰表达式 如:1 1 -
        private void reversePolish(char label, Stack<Integer> stack1) {
            int right = stack1.pop();
            int left = stack1.pop();
            switch (label) {
                case '+' :
                    stack1.push(left + right);
                    break;
                case '-' :
                    stack1.push(left - right);
                    break;
                case '*' :
                    stack1.push(left * right);
                    break;
                case '/':
                    stack1.push(left / right);
                    break;
    
            }
        }
    
        private void add(Stack<Integer> stack1, char c, String s, int i) {
            if (stack1.isEmpty()) {
                stack1.push(c-'0');
            } else {
                if (Character.isDigit(s.charAt(i-1))){//23
                    stack1.push(((int)stack1.pop())*10 + (c - '0'));
                } else {
                    stack1.push(c-'0');
                }
            }
        }
    
    
    
    }
    
    

    一共用到三个函数

    • calculate 主函数
    • reversePolish 逆波兰函数(输入3个元素)例:111 2 + -> 113
    • add 数字字符串处理,例:"123" -> 123

    calculate 主函数思路 示例:(1+2+(4+5+2)-3)+(6+8)

    将中缀表达式转化为后缀表达式

    • 准备两个栈,stack1、stack2。stack1存储操作数,stack2存储操作符
    • 遍历字符串s每一个字符c
    • c可能的值是' ', '(', ')' , '+' , '-' , '*' , '/','数字字符'
    • 操作符优先级:加减 < 乘除 ,先入栈的加减 > 后入栈的加减, 先入栈的乘除>后入栈的乘除
    char c 操作
    '(' 压入stack2
    ')' 依次将stack2中元素出栈到stack2,直至遇到'(' ,将'('出栈
    '+' 将栈中比'+'优先级高的操作符出栈到stack1,没有的话就不出栈。将'+'入栈 如果栈顶是'+'或'-'则'+'或'-'优先级比'+'高
    '-' 类似于'+'
    '*' 类似于'+'
    '/' 类似于'+'
    '数字' 如果stack1为空,直接将c-'0'压入stack1。如果c的前一个字符是数字,将栈stack1栈顶元素弹出乘以10加c-'0'的值 如111
    为了区分不同位置加号,使用'+_数字'表示加号
    (111+2+3)/2+1 -> 111 2 + 3 + 2 / 1 +
    c stack1 stack2 stack1优化
    '(' [] [] []
    '1' [] ['('] []
    '1' [1] ['('] [1]
    '1' [11] ['('] [11]
    '+_1' [111] ['('] [111]
    '2' [111] ['(', '+_1'] [111]
    '+_2' [111, 2] ['(', '+_2'] [111, 2]
    '3' [111, 2,'+_1'] ['(', '+_2'] [113]
    ')' [111, 2,'+_1',3] ['(', '+_2'] [113,3]
    '/' [111, 2,'+_1',3,'+_2'] [] [116]
    '2' [111, 2,'+_1',3,'+_2'] ['/'] [116]
    '+_3' [111, 2,'+_1',3,'+_2',2] ['/'] [116,2]
    '1' [111, 2,'+_1',3,'+_2',2,'/'] ['+_3'] [58]
    [111, 2,'+_1',3,'+_2',2,'/',1] ['+_3'] [58,1]
    • 栈stack1可以优化,当stack1入栈操作符时,改为直接执行逆波兰表达式(将stack1栈顶两个操作数弹出,记为left、right执行对应的加减乘除),stack1中只存操作数
    • 最后stack2中的栈顶弹出,stack1中两元素弹出,执行最后的逆波兰表达式,得到最终计算结果
  • 相关阅读:
    Android中AsyncTask与handler
    AndroidTimer使用(三)补充篇
    Android的消息机制(一)
    Android消息处理机制(二)
    java操作Excel文件(二)
    java操作excel
    Android APK反编译详解(附图)
    Android中Handler的使用方法——在子线程中更新界面
    Android线程间通信的Message机制
    AndroidTimer使用(二)
  • 原文地址:https://www.cnblogs.com/sweetorangezzz/p/12981756.html
Copyright © 2011-2022 走看看