逆波兰表达式(RPN)算法简单实现
一、预处理
给定任意四则运算的字符串表达式(中缀表达式),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 }
(完)