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;
        }
    }
  • 相关阅读:
    Dede 自定义频道解析
    没有什么想说的,但既然来了,也就留下一句
    Title和META标签参数详解,SEO优化中的title和META标签的重要性
    Jsoup HTML 解析器 用法介绍
    php 相关方面内容、
    Html.ActionLink Url.Action的用法
    Asp.Net MVC2.0 Url 路由入门实例篇
    asp.net mvc 在View中获取Url参数的值
    SSH2实现数据库和界面的分页
    struts2中的ModelDriven使用
  • 原文地址:https://www.cnblogs.com/czgxxwz/p/12899879.html
Copyright © 2011-2022 走看看