逆波兰表达式计算机的实现

本文介绍了如何实现逆波兰表达式(后缀表达式)的转换与计算。首先,详细阐述了从中缀表达式转为后缀表达式的过程,包括使用栈处理运算符和括号的步骤。然后,讨论了如何对后缀表达式进行求值,通过建立数据栈进行计算。整个实现包含了字符串转换、栈操作和优先级判断等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

逆波兰表达器的实现

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

逆波兰表达式(后缀表达式)
后缀表达式:平时使用的是中缀表达式

举例说明
(1 + 4) * 4 - 6
完成任务如下:
任务一:将一个中缀表达式转换为一个后缀表达式
举例说明:1+((2+3)4)-5转换为 集合ArrayList[1,2,3,+,4,,+,5,-]
计算结果为:16
实现思路:
第一步:
将字符串1+((2+3)4)-5转换为一个ArrayList[1,+,(, (,2,+,3,),,4,),-,5]
第二步:将集合中的中缀表达式转换为后缀表达式
1、建立一个栈用来存储临时的运算符和括号;
建立一个List集合用来存储后缀表达式;
建立一个整数型的top表示栈顶
2、遍历中缀表达式的集合
①:如果取出的是一个数字,直接加入到后缀表达式集合中
②:如果是左括号,直接进入临时栈
③:如果是右括号,则while循环,结束条件为遇到左括号,
执行体为弹出临时栈的运算符,并且加入到后缀表达式的集合中
④:如果遇到的是运算符:
如果临时栈为空,直接入栈,
如果不为空,判断运算符的优先级
while(当栈顶的运算符等级大于等于新的运算符的时候 && 临时栈不为空){
弹临时栈到结果栈
}新的运算符加入临时栈
3、遍历结束后将临时栈的运算符加入到结果集
第三步:得到对应的后缀表达式
任务二:完成一个后缀表达式的计算
实现思路:1、将得到的字符串转换为一个字符数组(里面只含有数字和运算符)
2、建立一个栈用来储存数据以便用来计算结果
3、如果输入的为数字则入栈,如果为运算符,则弹栈,用后弹出的数字加减乘除前面的数字
4、最后一个数据直接弹栈为最终结果

代码实现

package com.atguigu.polandNotation;


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

/**
 *
 * 逆波兰表达式(后缀表达式)
 * 后缀表达式:平时使用的是中缀表达式
 * 举例说明:(1 + 4) * 4 - 6
 *     对应的后缀表达式式为 1 4 + 4 * 6 -
 *          1 + 10 / 2 - 3 * ( 6 / 2)
 *      后缀表达式为:1 10 2 / + 3 6 2 / * -     结果:-3
 *
 *
 * 完成任务如下:
 *   任务一:将一个中缀表达式转换为一个后缀表达式
 *      举例说明:1+((2+3)*4)-5转换为 集合ArrayList[1,2,3,+,4,*,+,5,-]
 *        计算结果为:16
 *      实现思路:
 *      第一步:将字符串1+((2+3)*4)-5转换为一个ArrayList[1,+,(,(,2,+,3,),*,4,),-,5]
 *      第二步:将集合中的中缀表达式转换为后缀表达式
 *           1、建立一个栈用来存储临时的运算符和括号;
 *              建立一个List集合用来存储后缀表达式;
 *              建立一个整数型的top表示栈顶
 *           2、遍历中缀表达式的集合
 *             ①:如果取出的是一个数字,直接加入到后缀表达式集合中
 *             ②:如果是左括号,直接进入临时栈
 *             ③:如果是右括号,则while循环,结束条件为遇到左括号,
 *             执行体为弹出临时栈的运算符,并且加入到后缀表达式的集合中
 *             ④:如果遇到的是运算符:
 *                  如果临时栈为空,直接入栈,
 *                  如果不为空,判断运算符的优先级
 *                  while(当栈顶的运算符等级大于等于新的运算符的时候 && 临时栈不为空){
 *                      弹临时栈到结果栈
 *                  }新的运算符加入临时栈
 *           3、遍历结束后将临时栈的运算符加入到结果集
 *
 *
 *      第三步:得到对应的后缀表达式
 *
 *
 *   任务二:完成一个后缀表达式的计算
 *实现思路:1、将得到的字符串转换为一个字符数组(里面只含有数字和运算符)
 *        2、建立一个栈用来储存数据以便用来计算结果
 *        3、如果输入的为数字则入栈,如果为运算符,则弹栈,用后弹出的数字加减乘除前面的数字
 *        4、最后一个数据直接弹栈为最终结果
 */

public class PolandNotation {
    public static void main(String[] args) {
        //完成任务,将一个中缀表达式转换为一个后缀表达式
        //第一步:将字符串1+((2+3)*4)-5转换为一个ArrayList[1,+,(,(,2,+,3,),*,4,),-,5]
          String infixExpression = "1+((2+3)*4)-5";
          List<String> infixExpressionList = toinfixExpression(infixExpression);
        //第二步:将集合中的中缀表达式转换为后缀表达式
          List<String> suffList = transfromSuffExpression(infixExpressionList);
        //第三步:得到对应的后缀表达式
        System.out.println("中缀表达式" + infixExpression + "\t的后缀表达式为" + suffList);
        //第四步,计算
        int results  = count(suffList);
        System.out.println("中缀表达式" + infixExpression + "\t的最终的计算结果为" +  results);
        System.out.println("<-------------------------分割线-------------------------->");
        //输入带有空格的后缀表达式
//        String suffixExpression = "1 4 + 4 * 6 -";//14
        String suffixExpression = "1 10 2 / + 3 6 2 / * -";//-3
       List se = processingData(suffixExpression);
        System.out.println("后缀表达式" + suffixExpression + "的每个元素为" +se);
        //运算的方法
        int result  = count(se);
        System.out.println("后缀表达式" + suffixExpression + "的最终的计算结果为" +  result);
    }

    //将集合中的中缀表达式转换为后缀表达式
    private static List<String> transfromSuffExpression(List<String> infixExpressionList) {
//        1、建立一个栈用来存储临时的运算符和括号;
        // 建立一个List集合用来存储后缀表达式;
        List<String> suffList = new ArrayList<String> ();
        //建立一个栈,存储临时变量
        Stack<String> st = new Stack<String>();
        // 建立一个整数型的top表示栈顶
        int top = 0;
//        2、遍历中缀表达式的集合
        for (String item:infixExpressionList) {
            if (item.matches("\\d*")){// ①:如果取出的是一个数字,直接加入到后缀表达式集合中
                suffList.add(item);
            }else if ("(".equals(item)){//②:如果是左括号,直接进入临时栈
                st.push(item);
            }else if (")".equals(item)){
//            ③:如果是右括号,则while循环,结束条件为遇到左括号,
//               执行体为弹出临时栈的运算符,并且加入到后缀表达式的集合中
                while(!("(".equals(st.peek()))){
                    suffList.add(st.pop());
                }
                //弹出左括号
                st.pop();
            }else if ("+".equals(item) ||"-".equals(item) ||"*".equals(item) ||"/".equals(item)){
//              ④:如果遇到的是运算符:
// *                  如果临时栈为空,直接入栈,
                if (st.size() == 0){
                    st.push(item);
                }else {
// *                  如果不为空,判断运算符的优先级
                    while(st.size() != 0 && operatorLevel(st.peek()) >= operatorLevel(item)
                              ){
                        suffList.add(st.pop());
                    }
                    // 新的运算符加入临时栈
                    st.push(item);
//                   while(当栈顶的运算符等级大于等于新的运算符的时候 && 临时栈不为空){
// *                      弹临时栈到结果栈
//                   }
                }
            }
        }
//       3、遍历结束后将临时栈的运算符加入到结果集
        while(st.size() != 0){
            suffList.add(st.pop());
        }
        return suffList;
    }

    //将字符串1+((2+3)*4)-5转换为一个ArrayList[1,+,(,(,2,+,3,),*,4,),-,5]
    private static List<String> toinfixExpression(String infixExpression) {
        List<String> suffList = new ArrayList<String>();
        String str;//用于字符串拼接
        int i = 0;
        char c;//用来存储每次取到的字符串
       while(i < infixExpression.length()){
           //如果不是数字的话,直接进入集合
           if ((c = infixExpression.charAt(i)) < 48 || (c = infixExpression.charAt(i)) > 57){
               suffList.add("" +c);
               i++;
           }else{
               //如果是数字需要考虑多位数的问题
               str = "";
               while(i < infixExpression.length() &&(c = infixExpression.charAt(i)) >= 48 && (c = infixExpression.charAt(i)) <= 57){
                   str += c;
                   i++;
               }
               suffList.add(str);
           }
        }
        return suffList;
    }

    //为波兰计算器的计算部分,输入的se为一个集合
    private static int count(List<String> se) {
        Stack<String> stacks = new Stack<String>();
        int num1;
        int num2;
        int TemporaryValue;
        for (int i = 0; i < se.size(); i++) {
            if (se.get(i).matches("\\d+")){//为数字则入栈
                stacks.push(se.get(i));
            }else if("+".equals(se.get(i))){
                num2 = Integer.parseInt(stacks.pop());
                num1 = Integer.parseInt(stacks.pop());
                TemporaryValue = num1 + num2;
                stacks.push(String.valueOf(TemporaryValue));
            }else if("-".equals(se.get(i))){
                num2 = Integer.parseInt(stacks.pop());
                num1 = Integer.parseInt(stacks.pop());
                TemporaryValue = num1 - num2;
                stacks.push(String.valueOf(TemporaryValue));
            }else if("*".equals(se.get(i))){
                num2 = Integer.parseInt(stacks.pop());
                num1 = Integer.parseInt(stacks.pop());
                TemporaryValue = num1 * num2;
                stacks.push(String.valueOf(TemporaryValue));
            }else if("/".equals(se.get(i))){
                num2 = Integer.parseInt(stacks.pop());
                if (0 == num2){
                    throw new RuntimeException("除数不可以为零");
                }
                num1 = Integer.parseInt(stacks.pop());
                TemporaryValue = num1 / num2;
                stacks.push(String.valueOf(TemporaryValue));
            }
        }
        return Integer.parseInt(stacks.pop());

    }

    //将后缀表达式处理为一个字符转数组(去掉空格)
    private static List<String> processingData(String suffixExpression) {
        String[] se = suffixExpression.split(" ");
        List<String> valuse = new ArrayList<String>();
        for (String ses:se) {
            valuse.add(ses);
        }
        return valuse;
    }

    //判断运算符等级的方法
    public static int operatorLevel(String operator){
        int grade = 0;
        switch (operator){
            case "+":
                grade = 1;
                break;
             case "-":
                grade = 1;
                break;
             case "*":
                grade = 2;
                break;
             case "/":
                grade = 2;
                break;
            case "(":
                break;
            case ")":
                break;

                default:
                    System.out.println("输入有误");
                    break;
        }
        return grade;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值