package com.fbj.expression; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import com.fbj.expression.parse.Parse; import com.fbj.expression.token.NumToken; import com.fbj.expression.token.OprToken; import com.fbj.expression.token.Token; import com.fbj.expression.util.Util; public class Expression { public static List<Token> parse(String src){ if(src != null && !src.isEmpty()){ src = src.replaceAll(" +", "").replaceAll("÷", "/").replaceAll("×", "/"); int mark = 0; Token token = null; List<Token> tokens = new ArrayList<Token>(); while (mark < src.length()) { Parse parse = Util.getParse(String.valueOf(src.charAt(mark))); token = parse.parse(src, mark); if(token != null){ tokens.add(token); mark = token.getEnd(); }else { mark++; } } return tokens; } return null; } public static Token run(List<Token> tokens){ if(tokens != null){ //checkMinus(tokens); int mark = 0; int weight = 0; int weightOffset = 0; run : while (tokens.size() >= 2) { weightOffset = 0; weight = 0; // if(tokens.size() == 5){ // System.out.println(); // } System.out.print("要处理的表达式exp="); for(Token token2 : tokens){ System.out.print("[" +token2.getValue() + "]"); } System.out.println(); // System.out.println("还剩:" + tokens.size()); //int i = 0; //按优先级查找 Token token =null; for(int i =0 ; i <tokens.size() ; i++){ token = tokens.get(i); if(token.getWeight() > weight){ weight = token.getWeight(); weightOffset = i; } if(weight == Util.weights.length -1){ } } //System.out.println("最优先:" + tokens.get(weightOffset).getValue()); if(weight > 2){ //不是基础运算,继续化简 //首先找到他的配对标记 int flag = 0; int end = 0; Token subToken = null; token = tokens.get(weightOffset); for(int j = weightOffset+1 ; j < tokens.size(); j++){ subToken = tokens.get(j); //System.out.println(subToken.getValue()); if(subToken.getWeight() == weight){ //找到同优先级的,判断是否是一对 if(subToken.getValue().equals(token.getValue())){ flag++; }else if(subToken.getValue().equals(Util.getEnd(token.getValue()))){ flag--; } if(flag == -1){ //找到了 end = j; break; } } } if(end > 0){ //先算出结果 List<Token> subRTokens = tokens.subList(weightOffset + 1, end); Token subResultToken = run(subRTokens); //tokens.removeAll(subRTokens); // System.out.print("\n旧reg="); // for(Token token2 : tokens){ // System.out.print(token2.getValue()); // } tokens.remove(weightOffset +2); tokens.remove(weightOffset); weight = 0; } continue run; } // System.out.print("\nexp="); // for(Token token2 : tokens){ // System.out.print( token2.getValue()); // } // System.out.println(); //找完优先级开始运算 Token result = null; if(tokens.size() >=3 && weightOffset != 0){ result = calculation(tokens.get(weightOffset - 1), tokens.get(weightOffset + 1), tokens.get(weightOffset)); tokens.remove(weightOffset -1); tokens.remove(weightOffset -1); tokens.remove(weightOffset -1); tokens.add(weightOffset -1, result); }else { result = calculation(null, tokens.get(weightOffset + 1), tokens.get(weightOffset)); tokens.remove(0); tokens.remove(0); tokens.add(0 , result); } } return tokens.get(0); } return null; } public static Token calculation(Token pre , Token next , Token opr){ if(next instanceof NumToken && opr instanceof OprToken){ if(pre == null){ if ("-".equals(opr.getValue())) { next.setValue("-" +next.getValue()); } return next; }else if (next instanceof NumToken ){ String op = opr.getValue(); if(pre.getC().equals(Double.class) || next.getC().equals(Double.class) || "/".equals(opr.getValue())){ BigDecimal bigDecimal = new BigDecimal(pre.getValue()); BigDecimal bigDecimal2 = new BigDecimal(next.getValue()); BigDecimal result = null; if("+".equals(op)){ result = bigDecimal.add(bigDecimal2); }else if ("-".equals(op)) { result = bigDecimal.subtract(bigDecimal2); }else if ("*".equals(op)) { result = bigDecimal.multiply(bigDecimal2); }else if ("/".equals(op)) { result = bigDecimal.divide(bigDecimal2 , 9 , BigDecimal.ROUND_CEILING); } Token token = new NumToken(); token.setC(Double.class); token.setValue(result.toString().replaceAll("0+$", "")); return token; }else { Integer integer1 = new Integer(pre.getValue()); Integer integer2 = new Integer(next.getValue()); Integer result = null; if("+".equals(op)){ result = integer1 + integer2; }else if ("-".equals(op)) { result = integer1 - integer2; }else if ("*".equals(op)) { result = integer1 * integer2; }else if ("/".equals(op)) { result = integer1 / integer2; } Token token = new NumToken(); token.setC(Integer.class); token.setValue(result.toString()); return token; } } } return null; } public static Token start(String exp){ List<Token> tokens = Expression.parse(exp); return run(tokens); } public static void main(String[] args) { String exp = "-(10 * 2) +(-9*45.8)/4*3-2"; //List<Token> tokens = Expression.parse(exp); // for(Token token : tokens) // System.out.println(token.getValue() + "," + token.getWeight()); Token token = start(exp); System.out.println("\n" +exp + "="+token.getValue()); } public static void checkMinus(List<Token> tokens){ Token pre = null; Token c = null; for(int i = 0 ; i < tokens.size() ; i++){ c = tokens.get(i); if("-".equals(c.getValue())){ if(pre == null || pre instanceof OprToken){ if((i+1 < tokens.size())){ Token next = tokens.get(i+1); if(next instanceof NumToken){ next.setValue("-" + next.getValue()); tokens.remove(i); } } } } pre = c; } } public static void print(String title , List<Token> tokens){ System.out.print("\n"+title+"表达式"); for(Token token : tokens){ System.out.print(token.getValue()); } System.out.println(); } }
package com.fbj.expression.util; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.transform.Templates; import com.fbj.expression.parse.NumParse; import com.fbj.expression.parse.OprParse; import com.fbj.expression.parse.Parse; import com.fbj.expression.parse.StopParse; import com.fbj.expression.token.Token; public class Util { public final static String stopReg = "[\\(\\)\\[\\]\\{\\}]";//停止符号 public final static String stopString = "}])";//停止符号 public final static String oprReg = "[\\+\\-\\*/]";//运算符号 public final static String numReg = "\\d";//数值符号 public final static String weights[] = new String[]{"num" , "opr" , "" , "stop"}; private static List<String> regs; private static Map<String, Parse> parses; private static Map<String, String> stops; static{ regs = new ArrayList<String>(); regs.add(stopReg); regs.add(oprReg); regs.add(numReg); parses = new HashMap<String, Parse>(); parses.put(stopReg, new StopParse()); parses.put(oprReg, new OprParse()); parses.put(numReg, new NumParse()); stops = new HashMap<String, String>(); stops.put("{" , "}"); stops.put("[" , "]"); stops.put("(", ")"); } public static List<String> getRegs(){ return regs; } public static Parse getParse(String input) { if(input == null) return null; for (int i = 0; i < 3; i++) { if(input.matches(regs.get(i))){ return parses.get(regs.get(i)); } } return null; } /** * 获取原算法的优先级 * @return */ public static int getWeight(String type , String value){ if(type == null) return -1; //System.out.println(weights[i]); if("stop".equals(type)){ int w = stopString.indexOf(value); if(w == -1){ w = stopString.indexOf(stops.get(value)); } return 3 + w; }else if("opr".equals(type)) { if("*".equals(value) || "/".equals(value)){ return 2; }else { return 1; } }else { return 0; } } public static void main(String[] args) { System.out.println(parses.get(regs.get(2))); } public static String getEnd(String start) { return stops.get(start); } }