代码的思路是通过正则判断计算每个最小的计算单元。以下是代码:
1 import java.math.BigDecimal; 2 import java.util.regex.Matcher; 3 import java.util.regex.Pattern; 4 5 /** 6 * 计算器工具类 7 * @author shuqi 8 * @date 2015-7-23 9 * @version since 1.0 10 */ 11 public class CalculatorUtil { 12 13 public static BigDecimal arithmetic(String exp){ 14 if(!exp.matches("//d+")){ 15 String result = parseExp(exp).replaceAll("[//[//]]", ""); 16 return new BigDecimal(result); 17 }else{ 18 return new BigDecimal(exp); 19 } 20 } 21 /** 22 * 最小计数单位 23 * 24 */ 25 PRivate static String minExp="^((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//]))[//+//-//*///]((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//]))$"; 26 /** 27 * 不带括号的运算 28 */ 29 private static String noParentheses="^[^//(//)]+$"; 30 /** 31 * 匹配乘法或者除法 32 */ 33 private static String priorOperatorExp="(((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//]))[//*///]((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//])))"; 34 /** 35 * 匹配加法和减法 36 */ 37 private static String operatorExp="(((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//]))[//+//-]((//d+(//.//d+)?)|(//[//-//d+(//.//d+)?//])))"; 38 /** 39 * 匹配只带一个括号的 40 */ 41 private static String minParentheses="//([^//(//)]+//)"; 42 43 /** 44 * 解析计算四则运算表达式,例:2+((3+4)*2-22)/2*3 45 * @param expression 46 * @return 47 */ 48 private static String parseExp(String expression){ 49 //方法进入 先替换空格,在去除运算两边的()号 50 expression=expression.replaceAll("//s+", "").replaceAll("^//(([^//(//)]+)//)$", "$1"); 51 52 //最小表达式计算 53 if(expression.matches(minExp)){ 54 String result=calculate(expression); 55 return Double.parseDouble(result)>=0?result:"["+result+"]"; 56 } 57 //计算不带括号的四则运算 58 if(expression.matches(noParentheses)){ 59 Pattern patt=Pattern.compile(priorOperatorExp); 60 Matcher mat=patt.matcher(expression); 61 if(mat.find()){ 62 String tempMinExp=mat.group(); 63 expression=expression.replaceFirst(priorOperatorExp, parseExp(tempMinExp)); 64 }else{ 65 patt=Pattern.compile(operatorExp); 66 mat=patt.matcher(expression); 67 68 if(mat.find()){ 69 String tempMinExp=mat.group(); 70 expression=expression.replaceFirst(operatorExp, parseExp(tempMinExp)); 71 } 72 } 73 return parseExp(expression); 74 } 75 76 //计算带括号的四则运算 77 Pattern patt=Pattern.compile(minParentheses); 78 Matcher mat=patt.matcher(expression); 79 if(mat.find()){ 80 String tempMinExp=mat.group(); 81 expression=expression.replaceFirst(minParentheses, parseExp(tempMinExp)); 82 } 83 return parseExp(expression); 84 } 85 /** 86 * 计算最小单位四则运算表达式(两个数字) 87 * @param exp 88 * @return 89 */ 90 private static String calculate(String exp){ 91 exp=exp.replaceAll("[//[//]]", ""); 92 String number[]=exp.replaceFirst("(//d)[//+//-//*///]", "$1,").split(","); 93 BigDecimal number1=new BigDecimal(number[0]); 94 BigDecimal number2=new BigDecimal(number[1]); 95 BigDecimal result=null; 96 97 String operator=exp.replaceFirst("^.*//d([//+//-//*///]).+$", "$1"); 98 if("+".equals(operator)){ 99 result=number1.add(number2);100 }else if("-".equals(operator)){101 result=number1.subtract(number2);102 }else if("*".equals(operator)){103 result=number1.multiply(number2);104 }else if("/".equals(operator)){105 //第二个参数为精度,第三个为四色五入的模式106 result=number1.divide(number2,5,BigDecimal.ROUND_CEILING);107 }108 109 return result!=null?result.toString():null;110 }111 112 }
代码原本是一个博客,但记不得阿紫哪里了,原来代码没有注释而且存在BUG,我稍微修稿了一哈添加了注释。在这里做个笔记,方便以后用
新闻热点
疑难解答