java 實現 中序表示式轉後序表示式(逆波蘭式) 以及 後序表示式求值
阿新 • • 發佈:2018-12-13
第一次寫部落格,還是個學生,沒有什麼經驗,只是單純的記錄下自己實現一個問題的方法與思想,如有錯誤之處,請各路大神批評指出。
大概思想:跟參考部落格的思想差不多,單程式碼完全自己思考,實現過程有較多的if..else語句 看起來可能會有點暈。各處都有註釋有不懂的可以私信我。
這個程式還有一個好處是在於求後續表示式的時候,如果指定序列有其他字元(可能誤輸入)也可以生成對應的後續表示式,還會提醒哪個位置是哪個字元有誤。比如指定序列為 String str = "3¥+9*7+(2*1】+7)*2^"; 程式執行結果如下:
完整程式碼如下:
package reversePolish; import java.util.*; public class ReversePolish{ public static void main(String args[]){ String str = "3+9*7+(2*1+7)*2"; System.out.println(reversePolish(str)); System.out.println(sumReversePolish(reversePolish(str))); } public static String reversePolish(String str){ //String[] strArray = str.split(""); String str1; char[] strArray = str.toCharArray(); String[] operator = {"+","-","/","*","(",")"}; List<String> list = Arrays.asList(operator); LinkedList<String> list1 = new LinkedList<String>(); //輸出棧 LinkedList<String> list2 = new LinkedList<String>(); //操作符棧 for(int i = 0;i < strArray.length; i++){ /*該部分為查bug過程 ,一步一步看輸出是否一致 if(i == 14) { Iterator<String> it1 = list1.iterator(); Iterator<String> it2 = list2.iterator(); while(it1.hasNext()) { System.out.print(it1.next() + " ,"); } System.out.println(); while(it2.hasNext()) { System.out.print(it2.next() + " ,"); } System.out.println(); //System.exit(-1); }*/ if(Character.isDigit(strArray[i]) || Character.isLetter(strArray[i])){ //如果是運算元或者字母直接輸出 list1.add(Character.toString(strArray[i])); }else if(list.contains(Character.toString(strArray[i]))){ if(list2.size() == 0){ list2.addFirst(Character.toString(strArray[i])); //操作符入棧 }else { if(Character.toString(strArray[i]).equals("(")){ list2.addFirst(Character.toString(strArray[i])); //操作符入棧 } else if(Character.toString(strArray[i]).equals(")")){ String[] strA = list2.toArray(new String[0]); for(int j = 0;j < strA.length;j++) { do{ if(list2.size() == 0) { //這裡寫不寫都行,因為有括號不可能在第一個位置 }else { if(strA[j].equals("(")){ list2.pollFirst(); j = strA.length - 1; }else{ list1.add(list2.pollFirst()); } } }while(strA[j].equals("(")); } } //如果是加號或者減號,則除了遇到左括號,全部要出棧 else if(Character.toString(strArray[i]).equals("+") || Character.toString(strArray[i]).equals("-")){ String[] strB = list2.toArray(new String[0]); //要對操作符棧進行操作,所以不能使用Iterator進行操作(iterator操作的時候不能進行list的改動) if(strB[0].equals("(")){ list2.addFirst(Character.toString(strArray[i])); }else { for(int k = 0;k < strB.length;k++) { if(strB[k].equals("(")) { list2.addFirst(Character.toString(strArray[i])); k = strB.length - 1; //遇到左括號直接入棧,跳出迴圈,下面類似 }else { do{ if(list2.size() == 0) { list2.addFirst(Character.toString(strArray[i])); }else { list1.add(list2.pollFirst()); } }while(strB[k].equals("(")); } } } if(list2.size() == 0){ //因為棧裡面的資料都出棧了,所以剛掃描的符號要進棧,前提是沒有左括號 list2.addFirst(Character.toString(strArray[i])); } } //如果是乘號或者除號,棧頂元素為+或者-或者(進棧,*或者、出棧 else if(Character.toString(strArray[i]).equals("*") || Character.toString(strArray[i]).equals("/")){ String[] strC = list2.toArray(new String[0]); if(strC[0].equals("(")) { list2.addFirst(Character.toString(strArray[i])); }else { for(int l = 0;l < strC.length;l++) { if(strC[l].equals("(")) { list2.addFirst(Character.toString(strArray[i])); l = strC.length - 1; }else { do{ if(list2.size() == 0){ list2.addFirst(Character.toString(strArray[i])); }else { if(strC[l].equals("*") || strC[l].equals("/")){ list1.add(list2.pollFirst()); }else if(strC[l].equals("+") || strC[l].equals("-")){ list2.addFirst(Character.toString(strArray[i])); }else {} } }while(strC[l].equals("(")); } } } if(list2.size() == 0){ list2.addFirst(Character.toString(strArray[i])); } } } } else { System.out.println("輸入字串中的第個" + i + "符號 " + strArray[i] + "無法識別,請核對!"); } } //字串掃描完畢,把操作符棧剩下的操作符依次取出到輸出棧 int len = list2.size(); for(int p = 0;p < len;p++){ list1.add(list2.pollFirst()); } String[] strOutput = list1.toArray(new String[0]); StringBuffer sb = new StringBuffer(); for(int i = 0; i < strOutput.length; i++){ sb. append(strOutput[i]); } str1 = sb.toString(); return str1; } //後序表示式求值,要求中序序列只能有數字不能有字母 public static int sumReversePolish(String str){ //char[] strArray = str.toCharArray(); String[] strArray = str.split(""); LinkedList<Integer> list1 = new LinkedList<Integer>(); //存運算元 int a = 0,b = 0,sum = 0; for (int i = 0; i < strArray.length; i++) { if(strArray[i].equals("+") || strArray[i].equals("-") || strArray[i].equals("*") || strArray[i].equals("/")){ sum = 0; a = list1.pollFirst(); //獲取第一個數 b = list1.pollFirst(); //獲取第二個數 switch(strArray[i]) { case "+": sum = a + b; list1.addFirst(sum); break; case "-": sum = a - b; list1.addFirst(sum); break; case "*": sum = a * b; list1.addFirst(sum); break; case "/": sum = a / b; list1.addFirst(sum); break; } }else { list1.addFirst(Integer.valueOf(strArray[i]).intValue()); //數字的話直接加入列表 } } return sum; } }
如若轉載請註明出處,謝謝。