zoukankan      html  css  js  c++  java
  • 中缀表达式转后缀表达式(栈+队列)

    package 数据结构;
    
    import java.util.Arrays;
    import java.util.Queue;
    import java.util.Stack;
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * @program: java_每天一题
     * @description: 使用栈及队列实现中缀表达式转后缀表达式功能
     *            思路:1.初始化一个栈存放运算符s1,初始化一个队列存放后缀表达式q1
     *                 2.从左自右扫描中缀表达式
     *                 3.遇到数字,放入队列q1中
     *                 4.遇到运算符,进行比较运算符优先级
     *                 4.1 如果s1为空或者遇到左括号“(”,直接入栈
     *                 4.2 如果运算符优先级比栈顶优先级高,直接入栈
     *                 4.3 如果运算符优先级比栈顶优先级低,或者相等,想将s1顶层运算符弹出放入q1,再次转到4.1与新的顶层运算符相比较
     *                 5.遇括号时,如果是左括号“(”,直接入栈.如果是右括号,则依次弹出s1栈顶运算符,放入q1中,直到遇到左括号为止,此时将一对括号抛弃
     *                 6 重复步骤2-5,直到表达式最右边
     *                 7 将q1顺序输出 得到后缀表达式(逆波兰表达式)
     * @author: czg
     * @create: 2020-05-16 11:15
     */
    public class j_栈_中缀转后缀_逆波兰 {
        public static void main(String[] args) {
    
            System.out.println(Arrays.toString(infixToArrarSuffix("1+((2+3)*4)-5")));
        }
    
        /**
         * 中缀表达式转后缀表达式(返回字符串格式)
         * @param infix 中缀表达式
         * @return
         */
        public static String infixToStringSuffix(String infix){
            Stack<String> s1=new Stack<>();//存放运算符
            Queue<String> q1=new LinkedBlockingQueue<String>();//存放后缀表达式
            int index=0;//循环中缀表达式下标
            StringBuilder result=new StringBuilder();//结果
    
            while (true){
                //获得下标指定元素
                String element=getOneElement(infix,index);
                //如果是运算符
                if(isOperator(element)){
                    //s1.peek() 查看栈顶
                    if(s1.empty()||"(".equals(element)||"(".equals(s1.peek())){
                        //如果s1为空或者遇到左括号“(”,直接入栈
                        s1.push(element);
                    }else if(")".equals(element)){
                        //如果是右括号,则依次弹出s1栈顶运算符,放入q1中,直到遇到左括号为止,此时将一对括号抛弃
                        while (!s1.peek().equals("(")){
                            q1.add(s1.pop());
                        }
                        //丢弃左括号
                        s1.pop();
                    }else if(operaPriority(element)>operaPriority(s1.peek())){
                        //如果运算符优先级比栈顶优先级高,直接入栈
                        s1.push(element);
                    }else if(operaPriority(element)<=operaPriority(s1.peek())){
                        //如果运算符优先级比栈顶优先级低,或者相等,想将s1顶层运算符弹出放入q1,再次转到4.1与新的顶层运算符相比较
                        while (operaPriority(element)<=operaPriority(s1.peek())){
                            q1.add(s1.pop());
                            if(s1.empty()){
                                s1.push(element);
                                break;
                            }
                        }
                    }else {
                        throw new RuntimeException("存在未知运算符,无法计算");
                    }
                }else if(isInteger(element)){
                    //直接存入q1
                    q1.add(element);
                }
                index=index+element.length();
    
                //当到达末尾时,结束循环
                if(index>=infix.length()){
                    if(!s1.empty()){
                        q1.add(s1.pop());
                    }
                    break;
                }
            }
    
    
            while (!q1.isEmpty()){
                result.append(q1.poll());
            }
            return result.toString();
        }
    
        /**
         * 中缀表达式转后缀表达式(返回字符串数组格式)
         * @param infix 中缀表达式
         * @return
         */
        public static String[] infixToArrarSuffix(String infix){
            Stack<String> s1=new Stack<>();//存放运算符
            Queue<String> q1=new LinkedBlockingQueue<String>();//存放后缀表达式
            int index=0;//循环中缀表达式下标
    
            while (true){
                //获得下标指定元素
                String element=getOneElement(infix,index);
                //如果是运算符
                if(isOperator(element)){
                    //s1.peek() 查看栈顶
                    if(s1.empty()||"(".equals(element)||"(".equals(s1.peek())){
                        //如果s1为空或者遇到左括号“(”,直接入栈
                        s1.push(element);
                    }else if(")".equals(element)){
                        //如果是右括号,则依次弹出s1栈顶运算符,放入q1中,直到遇到左括号为止,此时将一对括号抛弃
                        while (!s1.peek().equals("(")){
                            q1.add(s1.pop());
                        }
                        //丢弃左括号
                        s1.pop();
                    }else if(operaPriority(element)>operaPriority(s1.peek())){
                        //如果运算符优先级比栈顶优先级高,直接入栈
                        s1.push(element);
                    }else if(operaPriority(element)<=operaPriority(s1.peek())){
                        //如果运算符优先级比栈顶优先级低,或者相等,想将s1顶层运算符弹出放入q1,再次转到4.1与新的顶层运算符相比较
                        while (operaPriority(element)<=operaPriority(s1.peek())){
                            q1.add(s1.pop());
                            if(s1.empty()){
                                s1.push(element);
                                break;
                            }
                        }
                    }else {
                        throw new RuntimeException("存在未知运算符,无法计算");
                    }
                }else if(isInteger(element)){
                    //直接存入q1
                    q1.add(element);
                }
                index=index+element.length();
    
                //当到达末尾时,结束循环
                if(index>=infix.length()){
                    if(!s1.empty()){
                        q1.add(s1.pop());
                    }
                    break;
                }
            }
    
    
            String[] result=new String[q1.size()];//结果
            for (int i = 0; i < result.length; i++) {
                result[i]=q1.poll();
            }
            return result;
        }
    
        //获得一个元素
        public static String getOneElement(String experssion,int index){
            int count=index;
            String data="";
            while (true){
                String temp="";
                if(experssion.length()==count+1)
                {
                    temp=experssion.substring(index);
                }else {
                    temp=experssion.substring(index,count+1);
                }
                if(isOperator(temp)){
                    data=temp;
                    break;
                }
                if(isInteger(temp)||temp.equals(".")){
                    data=temp;
                    if(experssion.length()==count+1){
                        break;
                    }
                    count++;
                }else if(data.length()>0){
                    break;
                }
            }
            return data;
        }
    
    
    
        //判断字符串是否为数字
        public static boolean isInteger(String str) {
            try {
                new Double(str);
                return true;
            }catch (Exception e){
                return false;
            }
        }
        //判断是否是运算符
        public static boolean isOperator(String str){
            return "+-*/()".indexOf(str)>=0;
        }
        //设置字符优先级
        public static int operaPriority(String opera){
            int result=0;
            switch (opera){
                case "+":
                case "-":  break;
                case "*":
                case "/":  result=1; break;
                default:
                    throw new RuntimeException("运算符优先级无法解析");
            }
            return result;
        }
    }
  • 相关阅读:
    Vuex
    浏览器渲染页过程描述
    mvvm 模式
    flex 布局
    js 浮点数计算
    3、异步编程-JS种事件队列的优先级
    高阶函数 debounce 和 throttle
    记录学习MVC过程,HTML铺助类(二)
    记录学习MVC过程,控制器方法和视图(一)
    修改以前项目遇到,所有页面继承BaseBage,Sesssion保存一个model,实现登录(记录一下)
  • 原文地址:https://www.cnblogs.com/czgxxwz/p/12899879.html
Copyright © 2011-2022 走看看