中缀表达式转后缀表达式以及后缀计算实现

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

public class methon {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("欢迎使用计算器!");
        System.out.println("要计算的式子:-->例如: 1+((2+3)*4)-5  ");
        String str = in.nextLine();
        //将中缀转换后缀表达式
        //先将字符串转换为中缀   放入List
        String expression =str;
        System.out.println(expression);
        //先将String转换为中缀表达式 存储到list
         List<String>s1 = ConvertList(expression);
        System.out.println(s1);
        //将存储到List中的中缀表达式(prefix) 变为 后缀表达式 (suffix)
        List<String> s2 =PrefixConverSuffix(s1);
        System.out.println(s2);
        //调用后缀表达式计算方法进行计算(Calculate)
        int result = Calculate(s2);
        System.out.println(result);
        //先定义一个逆波兰表达式
/*        String ni = "4 5 * 8 - 60 + 8 2 / +";
        List<String> list1 = get(ni);
        System.out.println(list1);
        int f = calculate(list1);
        System.out.println(f);*/
    }
    
    //最初的 自己导入后缀表达式   将他转为List
    public static List<String> get(String ni){
        String[] k = ni.split(" ");
        List<String> list = new ArrayList<>();
        for (String s:k
             ) {
            list.add(s);
        }
        return list;
    }
    

    //将中缀转为List
    public static List<String> ConvertList(String s){
        List<String> list = new ArrayList();
        int i = 0;//指针 用于遍历字符串
        String str; //多位数拼接
        char c;
        do{
            if((c = s.charAt(i))<48||(c = s.charAt(i))>57){ //每次都会赋值新的c  不用置空
                list.add(""+c);
                i++;
            }else{ //考虑多位数
                str = "";  //将str置空防止下一次拼接使用了上一次的字符
                while(i<s.length() && (c=s.charAt(i))>=48 && (c=s.charAt(i))<=57){
                    str +=c;
                    i++;
                }
                list.add(str);
            }
        }while(i<s.length());
        return list;
    }

    //将中缀的List 变为 后缀的list
    public static List<String> PrefixConverSuffix(List<String> list){
        Stack<String> s1 = new Stack<>(); //符号栈
        Stack<String> s2 = new Stack<>(); //储存栈


        //遍历list
        for (String item: list) {
            //如果是一个数  就入栈
            if(item.matches("\\d+")){
                s2.push(item);
            }else if(item.equals("(")){
                s1.push(item);
            }else if(item.equals(")")){
                while(!s1.peek().equals("(")){
                    s2.push(s1.pop());
                }
                s1.pop(); //将他弹出 使top下移动
            }else{
                //当s1 栈顶元素优先级比将要入栈的符号优先级高时 先将栈顶弹出再将当前符号入栈 (while更方便)
                while(s1.size()!=0&&(Priority(s1.peek())>=Priority(item))){
                    s2.push(s1.pop());
                }
                    s1.push(item);
            }
        }
        //完成遍历后将符号栈元素全部弹出到储存栈中去
        while(!s1.empty()){
            s2.push(s1.pop());
        }

    return s2;
    }
    
    //比较符号的优先级
    public static int Priority(String s){
        int value = 0;
        switch (s){
            case "+":
            case "-":
                value = 1;
                break;
            case "*":
            case "/":
                value = 2;
                break;
            default:
                /*System.out.println("不存在");*/
                //会报出几处正常的不存在问题
                break;
        }
        return value;
    }

  //将后缀表达式进行计算
    public static int Calculate(List<String> list){
        Stack<String> stack= new Stack<>();
        for (String k:list
             ) {
            if(k.matches("\\d+")){ //正则表达式
                stack.push(k);
            }else{
                //pop出两个数 运算 在入栈
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                //都是用后弹出的数去操作先弹出的数 和栈的性质有关 (先进后出)
                int res = 0;
                if(k.equals("+")){
                    res = num2+num1;
                }else if(k.equals("-")){
                    res = num1 - num2;
                }else if(k.equals("*")){
                    res = num1 * num2;
                }else if(k.equals("/")){
                    res = num1 / num2;
                }else{
                    throw new RuntimeException("运算符异常");
                }
                stack.push(res+"");
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

另附知识:

  1. 正则表达式的运用:matches("//d+")--> (+)表示多位数的判断;
  2. Integer.parseInt()  Integer包装类的使用;
  3. 栈的结构:先进后出-->(为什么计算时要用后弹出操作先弹出)
  4. split()的使用:  这里-->
    String[] k = ni.split(" ");  //分割形式的练习
  • ***试一试考虑加上空格、小数点的情况***

上一篇:LeetCode-162-寻找峰值


下一篇:01月26日总结