大話數據結構——使用棧實現簡單的四則運算
阿新 • • 發佈:2017-10-01
return flag system rar sub [0 contains ati convert
最近在讀《大話數據結構》,裏面有個例子是使用棧實現四則運算,現在我用java把這個功能實現試試
代碼如下:
package com.datastruct; import java.util.ArrayList; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StackPractice { private static ArrayList<String> symbolList; static{ symbolList = new ArrayList<>(); symbolList.add(SymbolEnum.ADD.getVal()); symbolList.add(SymbolEnum.SUBTRACT.getVal()); symbolList.add(SymbolEnum.MULTIPLY.getVal()); symbolList.add(SymbolEnum.DIVIDE.getVal()); symbolList.add(SymbolEnum.LEFT_BRACKET.getVal()); symbolList.add(SymbolEnum.RIGHT_BRACKET.getVal()); } public static void main(String[] args) { String exp = "9+(3-1)*3+10/2"; try { String exp2 = convertExp(exp); System.out.println(cal(exp2)); } catch (Exception e) { System.out.println(e.getMessage()); } } private static boolean isNumeric(String str){ Pattern pattern = Pattern.compile("[0-9]*"); Matcher isNum = pattern.matcher(str); if( !isNum.matches() ){ return false; } return true; } /** * 計算後綴表達式值 * @return */ private static int cal(String exp){ String[] expArr = exp.split(" "); Stack<String> calStack = new Stack<String>(); for(int i=0;i<expArr.length;i++){ String tmp = expArr[i]; if(isNumeric(tmp)){//數字入棧 calStack.push(tmp); }else{ int num1 = Integer.parseInt(calStack.pop());//棧頂彈出1 int num2 = Integer.parseInt(calStack.pop());//棧頂彈出2 switch (tmp) { case "-": calStack.push(num2 - num1 + ""); break; case "+": calStack.push(num2 + num1 + ""); break; case "*": calStack.push(num2 * num1 + ""); break; case "/": calStack.push(num2 / num1 + ""); break; default: break; } } } return Integer.parseInt(calStack.pop()); } /** * 中綴表達式轉為後綴表達式 * @return */ private static String convertExp(String exp) throws Exception{ //字符串轉數組 char[] expArr = exp.toCharArray(); StringBuffer sb = new StringBuffer(); Stack<String> symbolStack = new Stack<>(); boolean isLastCharNumberFlag = true; for(int i = 0;i<expArr.length;i++){ char curChar = expArr[i]; //若為數字添加 若為符號則放入棧計算 if(Character.isDigit(curChar)){ if(isLastCharNumberFlag){ sb.append(curChar); }else{ sb.append(" ").append(curChar); } isLastCharNumberFlag = true; }else if(symbolList.contains(String.valueOf(curChar))){//符號 // String symbol = String.valueOf(curChar); if(SymbolEnum.RIGHT_BRACKET.getVal().equals(symbol) ) { //如果是右括號,得匹配左括號 String symbolStr = symbolStack.pop(); while(!SymbolEnum.LEFT_BRACKET.getVal().equals(symbolStr)){ sb.append(" ").append(symbolStr); symbolStr = symbolStack.pop(); } isLastCharNumberFlag = false; continue; }else if(SymbolEnum.DIVIDE.getVal().equals(symbol) || SymbolEnum.MULTIPLY.getVal().equals(symbol) ){ }else{ if(symbolStack.isEmpty()){ symbolStack.push(symbol); continue; } String symbolStr = symbolStack.peek(); if(SymbolEnum.DIVIDE.getVal().equals(symbolStr) || SymbolEnum.MULTIPLY.getVal().equals(symbolStr)){ while(!symbolStack.isEmpty()){ sb.append(" ").append(symbolStack.pop()); } symbolStack.push(symbol); isLastCharNumberFlag = false; continue; } } symbolStack.push(symbol); isLastCharNumberFlag = false; } } while(!symbolStack.isEmpty()){ sb.append(" ").append(symbolStack.pop()); } return sb.toString(); } /** * 運算符枚舉 * @author Administrator * */ enum SymbolEnum{ ADD("+"), SUBTRACT("-"),MULTIPLY("*"),DIVIDE("/"),LEFT_BRACKET("("),RIGHT_BRACKET(")"); private String val; public String getVal(){ return val; } private SymbolEnum(String val){ this.val = val; } } }
程序暫時有些bug,如表達式合法性沒有校驗,不能輸入多個括號等
大話數據結構——使用棧實現簡單的四則運算