java中綴表達式轉後綴表達式
阿新 • • 發佈:2018-03-12
棧 邏輯運算 後綴表達式 逆波蘭 數據結構 四則運算是棧的重要應用之一
中綴表達式轉後綴表達式(逆波蘭算法)過程
- 從左到右遍歷中綴表達式
- 數字直接輸出為後綴表達式一部分
- 如果是符號,則判斷與棧頂元素的優先級
- 高於棧頂元素優先級直接入棧
- 低於或等於棧頂優先級棧頂元素出棧並輸出為後綴表達式一部分(註意這裏是遞歸比較棧頂元素的優先級並出棧),最後將當前元素入棧
直到遍歷完中綴表達式,最終輸出後綴表達式
下面是自己的實現源碼
package com.yhq.demospringboot; import org.apache.commons.lang3.StringUtils; import java.util.*; import java.util.concurrent.LinkedBlockingQueue; /** * yanghq * 2018/3/12 */ public class PreToAfterUtil { private static String leftChar = "("; private static String rightChar = ")"; private static Map<String, Integer> operationSymbolMap = new HashMap<>(); static { //初始化符號和優先級 operationSymbolMap.put(")",00); //右括號需匹配左括號,故優先級最低 operationSymbolMap.put("+",10); operationSymbolMap.put("-",10); operationSymbolMap.put("*",20); operationSymbolMap.put("/",20); operationSymbolMap.put("(",30); } /** * 中綴表達式轉化為後綴表達式 * @param strings * @return */ public Queue parsePre(String[] strings) { Stack<String> preStack = new Stack<String>(); Queue<String> queue = new LinkedBlockingQueue(); int i = 0; while(i<strings.length && Objects.nonNull(strings[i])) { if(StringUtils.isNumeric(strings[i])) { queue.add(strings[i]); }else if(StringUtils.isNotEmpty(strings[i])) { if(preStack.isEmpty()) { preStack.push(strings[i]); } else { String top = preStack.pop(); if(comparePriority(strings[i], top) < 0) { if(top.equals(leftChar)) { preStack.push(top); preStack.push(strings[i]); }else if(strings[i].equals(rightChar)) { appendTo(queue, top); preStack.pop(); } else{ appendTo(queue, top); popPre(preStack, strings[i], queue); preStack.push(strings[i]); //當前元素入棧 } } else { preStack.push(top); preStack.push(strings[i]); } } } i++; } while (!preStack.isEmpty()) { queue.add(preStack.pop()); } return queue; } /** * 遞歸比較當前元素與棧頂元素優先級 * @param preStatck * @param charTemp * @param queue */ public void popPre(Stack<String> preStatck, String charTemp, Queue queue) { if(!preStatck.isEmpty()) { String top = preStatck.pop(); if(comparePriority(charTemp, top) <= 0) { //低於棧頂元素,成為後綴表達式一部分 appendTo(queue, top); popPre(preStatck, charTemp, queue); } else { preStatck.push(top); } } } private void appendTo(Queue queue, String s) { if(!s.equals(leftChar) && !s.equals(rightChar)) { queue.add(s); } } /** * 比較優先級 * @param start * @param to * @return */ private int comparePriority(String start, String to) { return operationSymbolMap.get(start).compareTo(operationSymbolMap.get(to)); } /** * 計算後綴表達式結果 * @param queue * @return */ public int computeResult(Queue<String> queue) { int result = 0; if(Objects.isNull(queue)) { return result; } String s = queue.poll(); Stack<Integer> stack = new Stack(); while(Objects.nonNull(s)) { if(StringUtils.isNumeric(s)) { stack.push(Integer.valueOf(s)); }else if(!StringUtils.isEmpty(s)) { int first = 0; int second = 0; switch (s) { case "+" : first = stack.pop(); second = stack.pop(); result = first + second; stack.push(result); break; case "-" : first = stack.pop(); second = stack.pop(); result = second - first; stack.push(result); break; case "*" : first = stack.pop(); second = stack.pop(); result = first * second; stack.push(result); break; case "/" : first = stack.pop(); second = stack.pop(); result = second/first; stack.push(result); break; } } s = queue.poll(); } return result; } /** * 測試 * @param args */ public static void main(String[] args) { String[] pre = new String[]{"8","+","(","6","-","1",")","*","2","+","10","/","2"}; StringBuilder sb = new StringBuilder(); for (int i = 0; i < pre.length; i++) { sb.append(pre[i]); } System.out.println("前綴表達式:" + sb.toString()); Queue queue = new PreToAfterUtil().parsePre(pre); System.out.println("後綴表達式:" + queue.toString()); System.out.println("後綴表達式計算結果:" + new PreToAfterUtil().computeResult(queue)); } }
輸出結果展示
前綴表達式:8+(6-1)2+10/2
後綴表達式:[8, 6, 1, -, 2, , +, 10, 2, /, +]
後綴表達式計算結果:23
java中綴表達式轉後綴表達式