中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素【栈内的栈顶运算符>=遇到的运算符,就弹出】,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
后缀表达式的计算
用栈存放每个数字,每当便利到运算符时,弹出栈顶的两个元素,用第二个栈顶元素操作第一个
加法和乘法没有顺序,减法和除非注意先后问题即可

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    public int solve (String s) {
        // write code here
        String rpn=toSuffix(s);
        return getRPNval(rpn);
    }

    /**
     * 将  中缀表达式  转化为  后缀表达式
     */
    public String toSuffix(String infix){
        Map<Character, Integer> basic = new HashMap<Character, Integer>();
        basic.put('-', 1);
        basic.put('+', 1);
        basic.put('*', 2);
        basic.put('/', 2);
        basic.put('(', 0);//在运算中  ()的优先级最高,但是此处因程序中需要 故设置为0

        List<String> queue = new ArrayList<String>();                                    
        //定义队列  用于存储 数字  以及最后的  后缀表达式
        List<Character> stack = new ArrayList<Character>();                             
        //定义栈    用于存储  运算符  最后stack中会被 弹空

        char[] charArr = infix.trim().toCharArray();                                    
        //字符数组  用于拆分数字或符号
        String standard = "*/+-()";                                                        
        //判定标准 将表达式中会出现的运算符写出来
        char ch = '&';                                                                    
        //在循环中用来保存 字符数组的当前循环变量的  这里仅仅是初始化一个值  没有意义
        int len = 0;                                                                    
        //用于记录字符长度 【例如100*2,则记录的len为3 到时候截取字符串的前三位就是数字】
        for (int i = 0; i < charArr.length; i++) {                                        
            //开始迭代

            ch = charArr[i];                                                            
            //保存当前迭代变量
            if(Character.isDigit(ch)) {                                                    
                //如果当前变量为 数字
                len++;
            }else if(Character.isLetter(ch)) {                                            
                //如果当前变量为  字母
                len++;
            }else if(ch == '.'){                                                        
                //如果当前变量为  .  会出现在小数里面
                len++;
            }else if(Character.isSpaceChar(ch)) {                                        
                //如果当前变量为 空格  支持表达式中有空格出现
                if(len > 0) {                                                            
                     //若为空格 代表 一段结束 ,就可以往队列中  存入了  【例如100 * 2  100后面有空格 就可以将空格之前的存入队列了】
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    
                    //往 队列存入 截取的 字符串
                    len = 0;                                                            
                    //长度置空
                }
                continue;                                                                
                //如果空格出现,则一段结束  跳出本次循环
            }else if(standard.indexOf(ch) != -1) {                                        
                //如果是上面标准中的 任意一个符号
                if(len > 0) {                                                            
                    //长度也有
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    
                    //说明符号之前的可以截取下来做数字
                    len = 0;                                                            
                    //长度置空
                }
                if(ch == '(') {                                                            
                    //如果是左括号
                    stack.add(ch);                                                        
                    //将左括号 放入栈中
                    continue;                                                            
                    //跳出本次循环  继续找下一个位置
                }
                if (!stack.isEmpty()) {                                                    
                    //如果栈不为empty
                    int size = stack.size() - 1;                                        
                    //获取栈的大小-1  即代表栈最后一个元素的下标
                    boolean flag = false;                                                
                    //设置标志位
                    while (size >= 0 && ch == ')' && stack.get(size) != '(') {            
                        //若当前ch为右括号,则 栈里元素从栈顶一直弹出,直到弹出到 左括号
                        queue.add(String.valueOf(stack.remove(size)));                    
                        //注意此处条件:ch并未入栈,所以并未插入队列中;
                        //同样直到找到左括号的时候,循环结束了,所以左括号也不会放入队列中
                        //【也就是:后缀表达式中不会出现括号】
                        size--;                                                            
                        //size-- 保证下标永远在栈最后一个元素【栈中概念:指针永远指在栈顶元素】
                        flag = true;                                                    
                        //设置标志位为true  表明一直在取()中的元素
                    }
                    while (size>=0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)){
                        //若取得不是()内的元素,并且当前栈顶元素的优先级>=对比元素 那就出栈插入队列
                        queue.add(String.valueOf(stack.remove(size)));                    
                        //同样  此处也是remove()方法,既能得到要获取的元素,也能将栈中元素移除掉
                        size--;
                    }
                }
                if(ch != ')') {                                                            
                    //若当前元素不是右括号
                    stack.add(ch);                                                        
                    //就要保证这个符号 入栈
                } else {                                                                
                    //否则就要出栈 栈内符号
                    stack.remove(stack.size() - 1);
                }
            }
            if(i == charArr.length - 1) {                                                
                //如果已经走到了  中缀表达式的最后一位
                if(len > 0) {                                                            
                    //如果len>0  就截取数字
                    queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
                }
                int size = stack.size() - 1;                                            
                //size表示栈内最后一个元素下标
                while (size >= 0) {                                                        
                    //一直将栈内  符号全部出栈 并且加入队列中  
                    //【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】
                    queue.add(String.valueOf(stack.remove(size)));
                    size--;
                }
            }

        }
        return queue.stream().collect(Collectors.joining(","));                            
        //将队列中元素以,分割 返回字符串
    }



    public int getRPNval(String equation){
        Stack<Integer> stack=new Stack<Integer>();
        String [] rpnString = equation.split(",");
        int a,b;
        for(int i=0;i<rpnString.length;i++){
            String c=rpnString[i];
            if(c.equals("+")){
                a=stack.pop();
                b=stack.pop();
                stack.add(b+a);
            }
            else if(c.equals("-")){
                a=stack.pop();
                b=stack.pop();
                stack.add(b-a);
            }
            else if(c.equals("*")){
                a=stack.pop();
                b=stack.pop();
                stack.add(b*a);
            }
            else if(c.equals("/")){
                a=stack.pop();
                b=stack.pop();
                stack.add(b/a);
            }
            else{
                 stack.add(Integer.parseInt(c));
            }
        }
        return stack.peek();
    }
}