后缀表达式(逆波兰表达式)计算器

package datastructure.stack;

import java.util.*;

/**
 * <h3>netty_lecture</h3>
 * <p>逆波兰计算器</p>
 *  1+((2+3)*4)-5  ==> 1 2 3 + 4 * + 5 1
 * @author : myron
 * @date : 2020-03-18 23:48
 **/
public class PolandNotation {

    private static final int MINAS = 0;
    private static final int PLUS = 0;
    private static final int MULTI = 1;
    private static final int DIV = 1;

    public static void main(String[] args){
        String expression = "1,+,(,(,200,+,3,),*,9,),-,5";
        List<String> list = middleExpressionToList(expression);
        List<String> suffixExp = middleExpToSuffixExp(list);
        System.out.println("中缀表达式:"+ list);
        System.out.println("后缀表达式:" + suffixExp);
        int result = calculate(suffixExp);
        System.out.println("结果为:" + result);
    }

    /**
     * 中缀表达式转List
     * @param expression
     * @return
     */
    public static List<String> middleExpressionToList(String expression){
        String[] split = expression.split(",");
        List<String> list = Arrays.asList(split);
        return list;
    }

    /**
     * 中缀表达式转后缀表达式list
     * @param middleExpList
     * @return
     */
    public static List<String> middleExpToSuffixExp(List<String> middleExpList){
        Stack<String> s1 = new Stack<>();
        List<String>  s2 = new ArrayList<>();

        for (String oper:middleExpList){
            int priority = getPriority(oper);
            if(oper.matches("\\d+")){
                s2.add(oper);
            }else if("(".equals(oper)) {
                s1.push(oper);
            } else if(")".equals(oper)){
                while(!"(".equals(s1.peek())){
                    s2.add(s1.pop());
                }
                s1.pop();
            }else{
                while(s1.size() != 0 && priority <= getPriority(s1.peek())){
                    s2.add(s1.pop());
                }
                s1.push(oper);
            }
          }

        while(s1.size() != 0){
            s2.add(s1.pop());
        }
        return s2;
    }
    /**
     * 计算方法
     * @param list :后缀表达式
     * @return
     */
    public static int calculate(List<String>list){
        //创建栈
        Stack<String> stack = new Stack<>();
        //遍历表达式list
        for(String str: list){
            /**正则匹配,是数字,入栈*/
            if(str.matches("\\d+")){
              stack.push(str);
            /**运算符,则弹出两位数,进行运算*/
            }else{
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int result = 0;
                if(str.equals("+")){
                    result = num1 + num2;
                }else if(str.equals("-")){
                    result = num2 - num1;
                }else if(str.equals("*")){
                    result = num1 * num2;
                }else if(str.equals("/")){
                    result = num2/num1;
                }else{
                    throw new RuntimeException("不支持该符号!");
                }
                //预算结果入栈
                stack.push(result + "");
            }
        }
        //返回运算结果
        return Integer.parseInt(stack.pop());
    }

    /**
     * 获取符号的优先级
     */
    public static int getPriority(String oper){
        if (oper.equals("+")) {
            return PLUS;
        }else if(oper.equals("-")){
            return MINAS;
        }else if(oper.equals("*")){
            return MULTI;
        }else if(oper.equals("/")){
            return DIV;
        }
        return -1;
    }
}

原文地址:https://www.cnblogs.com/mmh760/p/12527206.html

时间: 2024-10-09 21:04:08

后缀表达式(逆波兰表达式)计算器的相关文章

JavaScript实现计算后缀表达式(逆波兰表达式)以及将中缀表达式转为后缀表达式

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子: 正常的表达式 逆波兰表达式 a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)d ---> a,d,b,c,-,,+ a=1+3 ---> a=1,3 + http=(smtp+http+telnet)/1024 写成什么呢? http=smtp,http,telnet,+,+,1

Java解析字符串表达式--逆波兰表达式的计算

问题来由: 读入一个字符串形式的四则运算表达式,输出对应的计算结果.如读入的是"6 * ( 5 + ( 2 + 3) * 8 + 3)",那么解析后的输出结果应为288. 思路: 一般的计算过程是这样的,首先计算优先级最高的小括号里面的内容,即"( 5 + ( 2 + 3) * 8 + 3)", 将"2 + 3"的计算结果并存为A,接着用计算"A*8",并存为B 计算"5+B+3",结果存为C 最后计算&q

Java解析字符串表达式--逆波兰表达式的生成

上回讲了如何计算后缀表达式,其实真正的难点在于如何将一个正常的字符串表达式(中缀表达式)变成一个后缀表达式.如将6 * ( 5 + ( 2 + 3) * 8 + 3)变为6 5 2 3 + 8 * + 3 + * 逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子: 正常的中缀表示 逆波兰表达式 a+b a,b,+ a+(b-c) a,b,c,-,+ a+(b-c)*d a,b,c,-,

栈的应用之中缀表达式转化为后缀表达式(逆波兰表达式)

1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define OK 1 5 #define ERROR 0 6 #define STACK_INIT_SIZE 20 7 #define STACK_INCREMENT 10 8 9 typedef char Elemtype; 10 typedef int Status; 11 12 typedef struct StackNode{ 13 Elemtype* base; 14 Elemt

逆波兰表达式(后缀表达式)

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出.逆波兰表达式又叫做后缀表达式.下面是一些例子: 正常的表达式 逆波兰表达式 a+b ---> a,b,+ a+(b-c) ---> a,b,c,-,+ a+(b-c)*d ---> a,b,c,-,d,*,+ a+d*(b-c)--->a,d,b,c,-,*,+ a=1+3 ---> a=1,3 + 通过后缀表达式计算表达式值的过程:顺序访问表达式的每一项,若该项为操作数,则将其压入栈中:若该项是操作符<o

简单计算机——逆波兰表达式

逆波兰数:逆波兰数由两部分组成(操作数,操作符)--是波兰表达式的一种,即操作符在操作数的后面. 形式:A+B*C-D = ABC*D-; (A+B)*C-D = AB+C*D-; 既然我们知道了,后缀表达式那我们表达式是唯一的吗?我们来看一组数据: 例如:(A+B)*C-D 和 C*(A+B)-D; 很显然第二个的表达式为:C*AB+D-;虽然对最后的结果无影响,但我们需要知道逆波兰的多样性. 注意事项: 1.如果出现1+23 = 123+,该如何判断它的数值呢? 可以利用分割符来进行很好的辅

递归--逆波兰表达式

用递归解决递归形式的问题例题:逆波兰表达式逆波兰表达式是一种把运算符前置的算术表达式(其实一般教科书上称这种表达式为波兰表达式) ,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4.本题求解逆波兰表达式的值,其中运算符包括+ - * /四个. 输入:输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数 输出:输出为一行,表达式的值. 简单来说,这种

求解逆波兰表达式(前缀表达式)

首先介绍一下逆波兰表达式 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4. 这个表达式的求法有很多种 这里介绍一种用递归求解的方法.. 时间复杂度O(n); 首先我们需要把表达式转换成运算符和数字. 用一个数组记录i位置是数字还是运算符. 如果是数字是浮点数的话可使用atof(str)把字符串转换为一个doubl

北京大学 程序设计与算法(二)逆波兰表达式

用递归解决递归形式的问题 逆波兰表达式 逆波兰表达式是一种把运算符前置的算数表达式,例如普通的表达式2+3的逆波兰表示法为+2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2+3)*3的逆波兰表示法为*+234.本题求解逆波兰表达式的值,其中运算符包括+-*/四个. 输入 输入为一行,其中运算符和运算数之间都用空格分隔,运算符是浮点数 输出 输出为一行,表达式的值. *+11.0 12.0 +24.0 35.0 --à(11.0+12.0)*(24.0+3

逆波兰表达式(后缀表达式)

前/中/后缀表达式的转换 自然表达式转换为前/中/后缀表达式,其实是很简单的.首先将自然表达式按照优先级顺序,构造出与表达式相对应的二叉树,然后对二叉树进行前/中/后缀遍历,即得到前/中/后缀表达式. 举例说明将自然表达式转换成二叉树: a×(b+c)-d ① 根据表达式的优先级顺序,首先计算(b+c),形成二叉树 ②然后是a×(b+c),在写时注意左右的位置关系 ③最后在右边加上 -d 然后最这个构造好的二叉树进行遍历,三种遍历的顺序分别是这样的: ① 前序遍历:根-左-右 ② 中序遍历:左-