六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 61|回复: 0

解析四则运算

[复制链接]

升级  52%

6

主题

6

主题

6

主题

童生

Rank: 1

积分
26
 楼主| 发表于 2013-2-4 22:34:41 | 显示全部楼层 |阅读模式
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);}}
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表