zoukankan      html  css  js  c++  java
  • 数据结构中缀表达式转后缀表达式以及后缀转中缀表达式

    最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要。为什么要学,可以看看这位博友的认识http://blog.csdn.NET/sdkfjksf/article/details/54380659

    直入主题:将缀表达式转为后缀表达式 以及将后缀表达式转为前缀表达式的实现。

    关于后缀转中缀,中缀转后缀的理论介绍,请先阅读其互转的理论知识,或者我转发的这篇文章,这里不再累赘,最好参考《数据结构与算法描述Java语言版》,接下来将会用java写。

    一、首先,怎么实现缀表达式转为后缀表达式

    缀表达式转为后缀表达式相对较为简单,对于中缀表达式转后缀,其思想是将 运算符(+-*/)往栈中放,数字就直接输出,然后通过每次扫描遇到的运算符优先级来判断出栈与入栈。直接上代码吧,代码中也有解释!

    package com.liyongdada.cn;  
      
    import java.util.Scanner;  
    import java.util.Stack;  
      
    public class StackTest {  
          
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
            Character token;  
            String exep;  
            int i=0;  
            //下面一句需要jre1.5  
            Stack<Character> s=new Stack<Character>();  
            Scanner sc=new Scanner(System.in);  
            exep=sc.next();  
            while((token=exep.charAt(i++))!='='){  
                if(token>='a' && token<='z'){  
                    System.out.print(token+" ");  
                }else{  
                    switch(token){  
                    case '+' :  
                        //省略掉的同时没写break;是因为,只要是小于或者等于的都会出栈,因此,继续执行下面语句  
                    case '-' :  
                        while(!s.isEmpty() && s.peek()!='('){  
                            System.out.print(s.pop()+" ");  
                        }  
                        s.push(token);  
                        break;  
                    case '*' :  
                    case '/' :  
                        while(!s.isEmpty() && s.peek()!='(' && s.peek()!='+' && s.peek()!='-'){  
                            System.out.print(s.pop()+" ");  
                        }  
                        s.push(token);  
                        break;  
                    case '(' :  
                        s.push(token);  
                        break;  
                    case ')' :  
                        while (!s.isEmpty() && s.peek()!='('){  
                            System.out.print(s.pop()+" ");  
                        }  
                        s.pop();  
                        break;  
                    case '^' :  
                        while (!s.isEmpty() && !(s.peek()=='(' || s.peek()=='^')){  
                            System.out.print(s.pop()+" ");  
                        }  
                        s.push(token);  
                        break;  
                    }  
                }  
            }  
            //最后检测,将剩余的全部出栈  
            while (!s.isEmpty()){  
                System.out.print(s.pop()+" ");  
            }  
        }  
      
    } 
    

     

     二、后缀表达式转换为中缀表达式代码

    首先,区别一下,这个后缀表达式转换为中缀表达式与前面不同,这里进行出入栈操作的是数字,而不是运算符。自己在网上找了很久,没发现有人写出这种转法的java代码,也许是没人放出来吧。于是,自己动手写了一个。思想与中缀表达式转换为后缀表达式有点不同。具体看代码吧!

    首先,我的思想是,将一个表达式中的运算符取出并用一个数组存储,对于怎么自动加括号,通过判断下一个运算符优先级。

    (假如: 有   6523+8*+3+*      我们很容易计算得到其中缀表达式为   ((3+2)*8+5+3)*6,所以,由第一个运算符  ”+“的下一个运算符 "*", 便可以知道,其 3+2 需要用括号括起来。其他方式也是,具体看代码。 )。最后,算法不是特别完美,欢迎指正!

    package com.liyongdada.cn;  
      
    import java.util.Scanner;  
    import java.util.Stack;  
      
    public class HouToZhong {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
            String expp;// 接收输入的表达式  
            String token;  
            int i = 0;  
            int ssLength = 0;// 记录运算符数组的大小  
            int charIndex = 0; // 用于记录已输出运算符的个数  
            Scanner sc = new Scanner(System.in);  
            expp = sc.next();  
            //计算表达式中,有多少个运算符  
            for (int j = 0; j < expp.length(); j++) {  
                if (!Character.isDigit(expp.charAt(j))) {  
                    ssLength += 1;  
                }  
            }  
            //定义大小  
            char[] ss = new char[ssLength];  
            int sj = 0;  
            //依次赋值  
            for (int j = 0; j < expp.length(); j++) {  
                if (!Character.isDigit(expp.charAt(j))) {  
                    ss[sj++] = expp.charAt(j);  
                }  
            }  
            //泛型为String类型,这可以避免每次复写掉  
            Stack<String> s = new Stack<String>();  
            String pop1, pop2;//用于接收每次取出的栈顶字符串  
            while (!(token = expp.substring(i, ++i)).equals("=")) {  
                if (token.matches("[0-9]?")) {  
                    s.push(token);  
                } else {  
                    // 只有jre1.7才能使用字符串作为switch中的值  
                    switch (token.charAt(0)) {  
                    case '+':  
                        if (charIndex < ssLength - 1) {  
                            pop1 = s.pop();  
                            pop2 = s.pop();  
                            if (ss[charIndex + 1] == '*'  
                                    || ss[charIndex + 1] == '/') {  
                                //调用自定义方法  
                                s.push(mixExpp(pop2, pop1, "+"));  
                            } else  
                                s.push(pop2 + "+" + pop1);  
                        } else {  
                            System.out.println("执行错误!+!");  
                            return;  
                        }  
                        charIndex++;  
                        break;  
                    case '-':  
                        if (charIndex < ssLength - 1) {  
                            pop1 = s.pop();  
                            pop2 = s.pop();  
                            if (!(ss[charIndex + 1] != '*' || ss[charIndex + 1] != '/')) {  
                                s.push(mixExpp(pop2, pop1, "-"));  
                            } else  
                                s.push(pop2 + "-" + pop1);  
                        } else {  
                            System.out.println("执行错误!-!");  
                            return;  
                        }  
                        charIndex++;  
                        break;  
                    case '*':  
                        pop1 = s.pop();  
                        pop2 = s.pop();  
                        s.push(pop2 + "*" + pop1);  
                        charIndex++;  
                        break;  
                    case '/':  
                        pop1 = s.pop();  
                        pop2 = s.pop();  
                        s.push(pop1 + "/" + pop2);  
                        charIndex++;  
                        break;  
                    case '^':  
                        pop1 = s.pop();  
                        pop2 = s.pop();  
                        s.push(pop2 + "^" + pop1);  
                        charIndex++;  
                        break;  
                    }  
                }  
            }  
            // 取出最后一个  
            System.out.println(s.pop());  
        }  
      
        // 用于拼接括号的方法  
        public static String mixExpp(String one, String two, String fuhao) {  
            String str = "(" + one + fuhao + two + ")";  
            return str;  
        }  
      
    }
    

      

  • 相关阅读:
    HTML浏览器标题栏如何设置
    阿里团队常用的布局——双飞翼布局
    浏览器兼容性问题——IE不支持却很实用的CSS属性Outline和Child
    css选择器:基本选择器
    编程十年
    解决WX-IOS打开公众号网页出现的底部导航条
    Angular6路由复用与延迟加载的冲突解决——看看有备无患
    Ionic2 + Angular4 + JSSDK开发中的若干问题汇总
    [Linq Expression]练习自己写绑定
    [Linq To Sql]解决join时的Collation冲突
  • 原文地址:https://www.cnblogs.com/tc520/p/6680788.html
Copyright © 2011-2022 走看看