【java】中綴表達式轉后綴表達式 java實現


算法:

中綴表達式轉后綴表達式的方法:
1.遇到操作數:直接輸出(添加到后綴表達式中)
2.棧為空時,遇到運算符,直接入棧
3.遇到左括號:將其入棧
4.遇到右括號:執行出棧操作,並將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出。
5.遇到其他運算符:加減乘除:彈出所有優先級大於或者等於該運算符的棧頂元素【棧內的棧頂運算符>=遇到的運算符,就彈出】,然后將該運算符入棧
6.最終將棧中的元素依次出棧,輸出。

 

例如:【5+4*6/2+3+(4*5)/5】 =24

轉化之后的后綴表達式:【5 4 6 * 2 / + 3 + 4 5 *5 / +】

 

下面使用java實現 中綴表達式轉化后綴表達式。  【支持多位數字,支持小數,支持+-*/()運算符】

  1 package com.agen.exchangePox;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Arrays;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8 import java.util.stream.Collectors;
  9 
 10 import org.junit.Test;
 11 
 12 public class InfixInToSuffix {
 13     /**
 14      *提前將 符號的優先級定義好
 15      */
 16     private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();
 17     static {
 18         basic.put('-', 1);
 19         basic.put('+', 1);
 20         basic.put('*', 2);
 21         basic.put('/', 2);
 22         basic.put('(', 0);//在運算中  ()的優先級最高,但是此處因程序中需要 故設置為0
 23     }
 24     
 25     @Test
 26     public void test(){
 27         String a = toSuffix("55.6+4*60/2+33+(4.7*5.6)/5");//傳入 一串 算數公式  
 28         System.out.println(a);
 29         System.out.println(dealEquation(a));
 30         
 31         
 32     }
 33     
 34     /**
 35      * 將  中綴表達式  轉化為  后綴表達式
 36      */
 37     public String toSuffix(String infix){
 38         List<String> queue = new ArrayList<String>();                                    //定義隊列  用於存儲 數字  以及最后的  后綴表達式
 39         List<Character> stack = new ArrayList<Character>();                             //定義棧    用於存儲  運算符  最后stack中會被 彈空
 40         
 41         char[] charArr = infix.trim().toCharArray();                                    //字符數組  用於拆分數字或符號
 42         String standard = "*/+-()";                                                        //判定標准 將表達式中會出現的運算符寫出來
 43         char ch = '&';                                                                    //在循環中用來保存 字符數組的當前循環變量的  這里僅僅是初始化一個值  沒有意義
 44         int len = 0;                                                                    //用於記錄字符長度 【例如100*2,則記錄的len為3 到時候截取字符串的前三位就是數字】
 45         for (int i = 0; i < charArr.length; i++) {                                        //開始迭代
 46             
 47             ch = charArr[i];                                                            //保存當前迭代變量
 48             if(Character.isDigit(ch)) {                                                    //如果當前變量為 數字  
 49                 len++;    
 50             }else if(Character.isLetter(ch)) {                                            //如果當前變量為  字母
 51                 len++;
 52             }else if(ch == '.'){                                                        //如果當前變量為  .  會出現在小數里面
 53                 len++;
 54             }else if(Character.isSpaceChar(ch)) {                                        //如果當前變量為 空格  支持表達式中有空格出現
 55                 if(len > 0) {                                                            //若為空格 代表 一段結束 ,就可以往隊列中  存入了  【例如100 * 2  100后面有空格 就可以將空格之前的存入隊列了】
 56                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //往 隊列存入 截取的 字符串 
 57                     len = 0;                                                            //長度置空
 58                 }
 59                 continue;                                                                //如果空格出現,則一段結束  跳出本次循環
 60             }else if(standard.indexOf(ch) != -1) {                                        //如果是上面標准中的 任意一個符號
 61                 if(len > 0) {                                                            //長度也有
 62                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));    //說明符號之前的可以截取下來做數字
 63                     len = 0;                                                            //長度置空
 64                 }
 65                 if(ch == '(') {                                                            //如果是左括號
 66                     stack.add(ch);                                                        //將左括號 放入棧中
 67                     continue;                                                            //跳出本次循環  繼續找下一個位置
 68                 }
 69                 if (!stack.isEmpty()) {                                                    //如果棧不為empty
 70                     int size = stack.size() - 1;                                        //獲取棧的大小-1  即代表棧最后一個元素的下標
 71                     boolean flag = false;                                                //設置標志位
 72                     while (size >= 0 && ch == ')' && stack.get(size) != '(') {            //若當前ch為右括號,則 棧里元素從棧頂一直彈出,直到彈出到 左括號
 73                         queue.add(String.valueOf(stack.remove(size)));                    //注意此處條件:ch並未入棧,所以並未插入隊列中;同樣直到找到左括號的時候,循環結束了,所以左括號也不會放入隊列中【也就是:后綴表達式中不會出現括號】
 74                         size--;                                                            //size-- 保證下標永遠在棧最后一個元素【棧中概念:指針永遠指在棧頂元素】
 75                         flag = true;                                                    //設置標志位為true  表明一直在取()中的元素
 76                     }
 77                     while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {    //若取得不是()內的元素,並且當前棧頂元素的優先級>=對比元素 那就出棧插入隊列
 78                         queue.add(String.valueOf(stack.remove(size)));                    //同樣  此處也是remove()方法,既能得到要獲取的元素,也能將棧中元素移除掉
 79                         size--;
 80                     }
 81                 }
 82                 if(ch != ')') {                                                            //若當前元素不是右括號  
 83                     stack.add(ch);                                                        //就要保證這個符號 入棧
 84                 } else {                                                                //否則就要出棧 棧內符號
 85                     stack.remove(stack.size() - 1);
 86                 }
 87             }
 88             if(i == charArr.length - 1) {                                                //如果已經走到了  中綴表達式的最后一位
 89                 if(len > 0) {                                                            //如果len>0  就截取數字
 90                     queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
 91                 }    
 92                 int size = stack.size() - 1;                                            //size表示棧內最后一個元素下標
 93                 while (size >= 0) {                                                        //一直將棧內  符號全部出棧 並且加入隊列中  【最終的后綴表達式是存放在隊列中的,而棧內最后會被彈空】
 94                     queue.add(String.valueOf(stack.remove(size)));
 95                     size--;
 96                 }
 97             }
 98             
 99         }
100         return queue.stream().collect(Collectors.joining(","));                            //將隊列中元素以,分割 返回字符串
101     }
102     
103 
104     /**
105      * 將 后綴表達式 進行  運算 計算出結果
106      * @param equation
107      * @return
108      */
109     public String dealEquation(String equation){
110         String [] arr = equation.split(",");                                    //根據, 拆分字符串
111         List<String> list = new ArrayList<String>();                            //用於計算時  存儲運算過程的集合【例如list中當前放置  100   20  5  /  則取出20/5 最終將結果4存入list   此時list中結果為  100  4 】
112         
113         
114         for (int i = 0; i < arr.length; i++) {                                    //此處就是上面說的運算過程, 因為list.remove的緣故,所以取出最后一個數個最后兩個數  都是size-2
115             int size = list.size();
116             switch (arr[i]) {
117             case "+": double a = Double.parseDouble(list.remove(size-2))+ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(a));     break;
118             case "-": double b = Double.parseDouble(list.remove(size-2))- Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(b));     break;
119             case "*": double c = Double.parseDouble(list.remove(size-2))* Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(c));     break;
120             case "/": double d = Double.parseDouble(list.remove(size-2))/ Double.parseDouble(list.remove(size-2)); list.add(String.valueOf(d));       break;
121             default: list.add(arr[i]);     break;                                    //如果是數字  直接放進list中
122             }
123         }
124         
125         return list.size() == 1 ? list.get(0) : "運算失敗" ;                    //最終list中僅有一個結果,否則就是算錯了
126     }
127     
128     
129 
130 }

 

 

其中的解釋比較詳細,不再贅述!!!

具體示例過程如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM