【Java】中缀表达式转后缀表达式&后缀表达式计算(逆波兰计算器)

该博客介绍了如何将中缀表达式转换为后缀表达式,以及如何对后缀表达式进行计算。通过使用栈来处理运算符和操作数,实现了从常见的数学式子到适合计算机处理的逆波兰表示法的转换,并提供了完整的Java代码实现。最终,通过示例展示了将中缀表达式"5+(2+3)*4-5"转换为后缀表达式并计算得出结果20的过程。
摘要由CSDN通过智能技术生成

中缀表达式:人们通常使用的式子,按照运算符的优先进行计算,例如:3*(5+7)-6,但中缀表达式不利于计算机的处理,便出现了后缀表达式。

后缀表达式:运算符位于操作数之后,例如 3*(5+7)-6,对应的后缀表达式为  3 5 7 + * 6 -

 

  •  将中缀表达式转为对应的List
    public static List<String> toInfixExpressionList(String s){
        //定义一个List,存放表达式
        List<String> ls = new ArrayList<String>();
        int i=0;//指针用于遍历中缀表达式字符串
        String str;//对多位数的拼接
        char c;//遍历的每一个字符存放在c
        do{
            //如果c是一个非数字,就要加入到ls
            if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){
                ls.add(""+c);
                i++;
            }else {//如果是一个数,需要考虑是否为多位数
                str="";
                while (i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=57){
                    str+=c;
                    i++;
                }
                ls.add(str);
            }
        }while (i<s.length());
        return ls;
    }
  •  将得到的中缀表达式对应的List——>后缀表达式对应的List
    public static List<String> parseSuffixExpression(List<String> ls){
        //定义一个符号栈,一个list存储中间结果
        Stack<String> s1 = new Stack<String>();
        List<String> s2 = new ArrayList<String>();
        //遍历s1
        for (String item:ls){
            //如果是一个数加入s2
            if (item.matches("\\d+")){
                s2.add(item);
            }else if (item.equals("(")){
                s1.push(item);
            }else if (item.equals(")")){
                //如果是一个右括号,则一次弹出s1栈中的运算符,并添加到s2,直到左括号为止,此时将这一对括号去掉
                while (!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();//将"("左括号弹去消除小括号
            }else {//当item的优先级小于等于s1栈顶的优先级,将s1栈顶的运算符弹出并加入到s2中,再次转到上一步
                while (s1.size()!=0&&Operation.getvalue(s1.peek())>=Operation.getvalue(item)){
                    s2.add(s1.pop());
                }
                //将item压入栈中
                s1.push(item);
            }
        }
        //将s1剩余的运算符依次弹出并加入s2
        while(s1.size()!=0){
            s2.add(s1.pop());
        }
        return s2;
    }
  • 完成对逆波兰表达式的运算
    public static int calculate(List<String> ls){
        Stack<String> stack = new Stack<String>();
        //遍历ls
        for (String item:ls) {
            //用正则表达式取值
            if (item.matches("\\d+")){//一次或多次
                stack.push(item);//入栈
            }else {//pop出两个数进行计算
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;

                if (item.equals("+")){
                    res = num1+num2;
                }else if (item.equals("-")){
                    res = num1-num2;
                }else if (item.equals("*")){
                    res = num1*num2;
                }else if (item.equals("/")){
                    res = num1/num2;
                }else{
                    throw new RuntimeException("运算符号有误");
                }
                stack.push(""+res);//将int转为字符串,也可以使用String.value(res)/res+""
            }

        }
        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 res = 0;
        switch (operation){
            case "+":
                res = ADD;break;
            case "-":
                res = SUB;break;
            case "*":
                res = MUL;break;
            case "/":
                res = DIV;break;
            default:
                break;
        }
        return res;
    }

}
  • 主方法
public static void main(String[] args) {
        String s = "5+(2+3)*4-5";
        List<String> infixElist = toInfixExpressionList(s);

        List<String> suffixEList = parseSuffixExpression(infixElist);
        System.out.println(s+"后缀表达式为"+suffixEList);

        int res = calculate(suffixEList);
        System.out.println("逆波兰表达式"+suffixEList+"的结果是:"+res);
    }
  • 输出结果
5+(2+3)*4-5后缀表达式为[5, 2, 3, +, 4, *, +, 5, -]
逆波兰表达式[5, 2, 3, +, 4, *, +, 5, -]的结果是:20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小俱的一步步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值