栈-Java实现逆波兰计算器

目录

    • 引言
    • 中缀表达式转后缀表达式
    • 后缀表达式的计算机求值
    • 实现逆波兰计算器

引言

  • 后缀表达式更适合计算式进行运算,但是人却不太容易写出来,尤其是表达式很长的情况下,因此在开发中,我们需要将中缀表达式转成后缀表达式

中缀表达式转后缀表达式

  1. 初始化两个栈:运算符栈s1和存储中间结果的栈s2

  2. 从左至右扫描中缀表达式

  3. 遇到操作数时,将其压s2;

  4. 遇到运算符,比较其与s1栈顶运算符的优先级;

    1. 如果s1为空,或栈底运算符为左括号“(”,则直接将此运算符入栈
    2. 否则,若优先级比栈顶运算符高,也将运算符压入s1
    3. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中断的栈顶运算符相比较;
  5. 遇到括号时:
    (1)如果是左括号“(”,则直接压入s1
    (2)如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃

  6. 重复步骤2至5,直到表达式的最右边

  7. 将s1中剩余的运算符依次弹出并压入s2

  8. 依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

后缀表达式的计算机求值

  • 从左到右扫描表达式,当遇到数字时,将数字压入堆栈,遇到操作符,弹出栈顶的两个数,用运算符对它们做出相应的计算,并将结果入栈,重复上述过程知道表达式最右项,最后运算得出的值即为表达式的结果

实现逆波兰计算器

import java.util.List;
import java.util.Stack;

public class Computer {

    public static void main(String[] args) {
        /**
         * (30+4)*5-6 = 30 4 + 5 * 6
         *
         * 4*5-8+60+8/2 = 4 5 * 8 - 60 + 8 2 /+
         */
        String expression = "( 30 + 4 ) * 5 - 6";
        //中缀表达式转后缀表达式(逆波兰表达式)
        List<String> list = convert(expression);
        System.out.println(list);
        int result = calculate(list);
        System.out.println("result= " + result);

    }
	/**
	*参考上述 中缀表达式转后缀表达式
	*/
    private static List<String> convert(String str){
        Stack<String> stack1 = new Stack<>();
        List<String> stack2 = new Stack<>();
        String[] arr = str.split(" ");

        for(String item: arr){
            if(item.matches("\\d+")){
                stack2.add(item);
            }else if(item.equals("(")){
                stack1.push(item);
            }else if(item.equals(")")){
                while (!stack1.peek().equals("(")){
                    stack2.add(stack1.pop());
                }
                stack1.pop();
            }else{
                /**
                 * 当item优先级小于等于stack1栈顶运算符,将stack1栈顶的运算弹出,加入stack2中,
                 * 再次转到(4.1)与stack中新的栈顶运算符相比较
                 */
                while (stack1.size()!=0&&Operation.getValue(stack1.peek())>=Operation.getValue(item)){
                    stack2.add(stack1.pop());
                }
                stack1.push(item);
            }
        }
        while (stack1.size()!=0){
            stack2.add(stack1.pop());
        }
        return stack2;
    }

    private static int calculate(List<String> list){
        Stack<String> stack = new Stack<>();
        for(String item:list){
            /**
             * 如果匹配到多个数字
             */
            if(item.matches("\\d+")){
                stack.push(item);
            }else {
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int result ;
                if(item.equals("+")){
                    result = num1 + num2;
                }else if(item.equals("-")){
                    result = num1 - num2;
                }else if(item.equals("*")){
                    result = num1*num2;
                }else if(item.equals("/")){
                    result = num1/num2;
                }else {
                    throw new RuntimeException("运算符错误");
                }
                stack.push(String.valueOf(result));
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

class Operation{
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static int getValue(String operation){
        int result = 0;
        switch (operation){
            case "+":
                result=ADD;
                break;
            case "-":
                result=SUB;
                break;
            case "*":
                result=MUL;
                break;
            case "/":
                result=DIV;
                break;
        }
        return result;
    }
}

你可能感兴趣的:(数据结构)