1. 程式人生 > >逆波蘭表達式(RPN)算法簡單實現

逆波蘭表達式(RPN)算法簡單實現

預處理 中綴表達式 trac 出棧 直接 bstr 總結 波蘭表達式 操作

算法分析:

一、預處理

給定任意四則運算的字符串表達式(中綴表達式),preDeal預先轉化為對應的字符串數組,其目的在於將操作數和運算符分離。

例如給定四則運算內的中綴表達式:

String infix = "100+8*5-(10/2)*5+10.5";

字符串數組化後得:

{"100","+","8","*","5","-","(","10","/","2",")","+","10.5"}

二、中綴表達式轉後綴表達式

規則:

遍歷中綴表達式,

A、如果遇到操作數直接輸出

B、如果遇到運算符,分情況:

B1:如果是*、/或者(這三個運算符,直接壓棧

B2:如果是),則出棧直到遇到(位置。(左括號和有括號並不參與拼接後綴表達式)。

B3:如果是+或者-,先彈棧直到棧空,再講當前的+或者-壓棧。

其中情況B可以總結:

遇到右括號出棧直到匹配左括號,遇到操作符,如果其優先級高於棧頂元素,則繼續壓棧,否則出棧。

三、計算後綴表達式

規則:

遍歷後綴表達式:

A、遇到操作數壓棧

B、遇到運算符則將棧頂和次棧頂兩個元素取出參與對應的運算,再將運算結結果壓棧。

java算法實現:

  1 package agstring;
  2 import java.util.*;
  3 
  4 
  5 public class RPN {
  6     public static String[] preDeal(String infix){
7 infix = infix.trim(); 8 int length = infix.length(); 9 ArrayList<String> infixOfArrayList = new ArrayList<String>(); 10 char currChar; 11 int index = 0; 12 final String regex = "\\+|-|\\*|\\/|\\(|\\)"; 13 for (int i = 0; i < length; i++) {
14 currChar = infix.charAt(i); 15 if(String.valueOf(currChar).matches(regex)){//運算符 16 if (index < i) { 17 infixOfArrayList.add(infix.substring(index,i));//add數字 18 } 19 infixOfArrayList.add(String.valueOf(currChar)); 20 index = i+1; 21 } 22 } 23 infixOfArrayList.add(infix.substring(index,length)); 24 return infixOfArrayList.toArray(new String[infixOfArrayList.size()]); 25 } 26 public static String[] getPostfix(String infix) { 27 String[] infixOfAry = preDeal(infix); 28 int length = infixOfAry.length; 29 ArrayDeque<String> stack = new ArrayDeque<String>(); 30 String currString = ""; 31 final String regex = "\\+|-|\\*|\\/|\\(|\\)"; 32 ArrayList<String> postfixOfArrayList = new ArrayList<String>(); 33 for (int i = 0; i < length; i++) { 34 currString = infixOfAry[i]; 35 if (currString.matches(regex)) {//symbol 36 if (currString.matches("\\*|\\/|\\(")) { 37 stack.offerFirst(currString); 38 }else {//),+,- 39 String top = ""; 40 if(currString.equals(")")){ 41 while(!stack.isEmpty()){ 42 top = stack.removeFirst(); 43 if (top.equals("(")) { 44 break; 45 } 46 postfixOfArrayList.add(top); 47 } 48 }else {//+ ,- 49 if (!stack.isEmpty()) { 50 top = stack.peekFirst(); 51 if (top.equals("*") || top.equals("/")) { 52 while(!stack.isEmpty()){ 53 postfixOfArrayList.add(stack.removeFirst()); 54 } 55 } 56 } 57 stack.offerFirst(currString); 58 } 59 } 60 }else {//number 61 postfixOfArrayList.add(currString); 62 } 63 } 64 while(!stack.isEmpty()){ 65 postfixOfArrayList.add(stack.removeFirst()); 66 } 67 return postfixOfArrayList.toArray(new String[postfixOfArrayList.size()]); 68 } 69 public static double computePostfix(String infix){ 70 String[] postfixAry = getPostfix(infix); 71 ArrayDeque<Double> stack = new ArrayDeque<Double>(); 72 int length = postfixAry.length; 73 String currString = ""; 74 final String regex = "\\+|-|\\*|\\/|\\(|\\)"; 75 double operandOne,operandTwo; 76 for (int i = 0; i < length; i++) { 77 currString = postfixAry[i]; 78 if (currString.matches(regex)) { 79 operandOne = stack.removeFirst(); 80 operandTwo = stack.removeFirst(); 81 switch (currString.charAt(0)) { 82 case ‘+‘: 83 stack.addFirst(operandTwo + operandOne); 84 break; 85 case ‘-‘: 86 stack.addFirst(operandTwo - operandOne); 87 break; 88 case ‘*‘: 89 stack.addFirst(operandTwo * operandOne); 90 break; 91 case ‘/‘: 92 stack.addFirst(operandTwo / operandOne); 93 break; 94 } 95 96 }else { 97 stack.addFirst(Double.parseDouble(currString)); 98 } 99 } 100 return stack.removeFirst(); 101 } 102 public static void main(String[] args) { 103 // TODO Auto-generated method stub 104 try { 105 String infix = "100+8*5-(10/2)*5+10.5"; 106 double result = computePostfix(infix); 107 System.out.println(result); 108 } catch (Exception e) { 109 // TODO: handle exception 110 e.printStackTrace(); 111 } 112 } 113 114 }

逆波蘭表達式(RPN)算法簡單實現