中缀表达式转换后缀表达式

别等时光非礼了梦想. 提交于 2019-12-19 05:43:21

记录点滴

  1. 转换思路
//中缀表达式转后缀表达式步骤
        /**
         * 小括号()不算运算符优先级,
         * 1.初始化两个栈,运算符栈s1,和存储中间结果的栈s2,
         * 2.从左至右扫描中缀表达式
         * 3.遇到数时,将其放入栈s2,
         * 4.遇到运算符时,比较其与s1栈顶运算符的优先级:
         *      4.1:如果s1为空,或为“(”左括号,直接放入栈s1
         *      4.2:否则、若优先级比栈顶元素高,也存入栈s1中,
         *      4.3:否则,将s1栈顶的元素取出,并存入s2中,再次转到步骤4中,与s1中新的栈顶元素比较
         * 5.遇到括号时,
         *      5.1:如果是左括号“( ” ,则直接存入s1中
         *      5.2:如果是右括号“ ) ”,则依次取出s1中的元素,放入s2中,直到遇到左括号“( ”为止
         * 6.重复步骤2-5知道遍历到表达式的最右端
         * 7.将s1中的符号一次取出 并存入s2
         * 8.依次取出s2中的元素,并输出,这时该结果的逆序,就是后缀表达式
         */

    2 . 代码

public class PolanNotation {
     public static void main(String[] args){

        String input = "(11+5)*2-6+3";
        System.out.println(transition(input)); //输出 后缀表达式
        System.out.println(calculate(transition(input))); //根据后缀表达式输出最后结果

     }


   //前缀表达式转换后缀表达式的方法
   public static ArrayList<String> transition(String input){
        Stack<String> s1 = new Stack();//符号栈
        Stack<String> s2 = new Stack();//数字栈
        String ch = "";
        for(int index = 0; index < input.length(); index++){
            String temp = String.valueOf(input.substring(index, index + 1).charAt(0)); //取出单个字符并转换成String
            if (temp.matches("\\d")){//匹配多位数字
                 if(index < input.length()-1){
                     if(String.valueOf(input.substring(index+1, index + 2).charAt(0)).matches("\\d")){
                         ch += temp;
                     }else {
                         ch += temp;
                         s2.push(ch);
                         ch = "";
                     }
                 }else {
                     ch += temp;
                     s2.push(ch);
                 }
            }else if (temp.equals("(")){
                s1.push(temp);
            }else if (temp.equals(")")){
                //则依次取出s1中的元素,放入s2中,直到遇到左括号“( ”为止
                boolean flag = true;
                while (flag){
                    if(s1.peek().equals("(")){
                        s1.pop();
                        flag = false;
                    }else {
                        s2.push(s1.pop());
                    }
                }
            }else {//剩下的就是运算符 +  -  *  /了
               /** 4.遇到运算符时,比较其与s1栈顶运算符的优先级:
                 *      4.1:如果s1为空,或为“(”左括号,直接放入栈s1
                 *      4.2:否则、若优先级比栈顶元素高,也存入栈s1中,
                 *      4.3:否则,将s1栈顶的元素取出,并存入s2中,再次转到步骤4中,与s1中新的栈顶元素比较
                 */
                if(s1.empty() || s1.peek().equals("(")){
                    s1.push(temp);
                }else{
                    //判断优先级
                    boolean flag = true;
                    while (flag) {
                        if(!s1.empty()) {
                            int i = priority(s1.peek());
                            int j = priority(temp);
                            if (j > i) {
                                s1.push(temp);
                                flag = false;
                            } else {
                                s2.push(s1.pop());
                            }
                        }
                        s1.push(temp);
                        flag = false;
                    }
                }

            }

        }
        //第七步
        while (!s1.empty()){
            s2.push(s1.pop());
        }
        //第八步  依次取出s2中的元素,并输出,这时该结果的逆序,就是后缀表达式
        ArrayList<String> arrayList = new ArrayList();
        while (!s2.empty()){
            arrayList.add(s2.pop());
        }
        Collections.reverse(arrayList);
        return arrayList;
    }


    //运算符优先级方法
    public static int priority(String oper){
        if(oper.equals("*") || oper.equals("/")){
            return 1;
        }else if(oper.equals("+") || oper.equals("-")){
            return 0;
        }else {
            return -1;
        }
    }


    //根据后缀表达式求出最终结果
    //计算,在栈中运算,每遇到一个运算符就取出两个数来计算,并将计算的值放入栈中
    public static int calculate(ArrayList<String> ls){
        Stack<String> stack = new Stack();
        //遍历list
        for(String a : ls){
            if(a.matches("\\d+")){ //匹配多位数   \\d只匹配单个数字
                stack.push(a);
            }else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int ele = 0;
                if(a.equals("+")){
                    ele = num1 + num2;
                }else if (a.equals("-")){
                    ele = num2 -num1;
                }else if (a.equals("*")){
                    ele = num2 * num1;
                }else if (a.equals("/")){
                    ele = num2 / num1;
                }else {
                    throw new RuntimeException("传入的运算符有误");
                }
                stack.push(ele+"");
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!