最近在做新项目,需要计算预先配置的表达式的结果。
表达式特点:
1,浮点类型
2,代变量参数
3,只限于简单计算符号
表达式类似于:"3*(4+a)/6"
程序:
import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * * @author chenlei * @2013-1-16 */ public class Formula { /** * 类型 */ private final static int NUMBER = 1; private final static int OPERATOR = 2; private final static int END_PAREN = 3; private final static int START_PAREN = 4; /** * 操作符优先级 */ private static Map<Character, Integer> priority; static{ priority = new HashMap<Character, Integer>(4); priority.put('-', 1); priority.put('+', 1); priority.put('*', 2); priority.put('/', 2); } /** * 后缀表达式 */ public List<String> postfix = new ArrayList<String>(); /** * 构造 * @param formula 公式 */ public Formula(String formula){ formula = formula.toLowerCase(); LinkedList<Character> stack = new LinkedList<Character>(); int type = 0; StringBuffer str= new StringBuffer(); for(int i = 0; i < formula.length(); i++){ char c = formula.charAt(i); if(c >= 48 && c <= 57 || c >= 97 && c <= 122 || c == 46){ type = NUMBER; str.append(c); }else{ if(str.length() != 0){ postfix.add(str.toString()); str.setLength(0); } switch(c){ case '+': case '-': case '*': case '/': if(type == 0 || type == OPERATOR || type == START_PAREN){ throw new RuntimeException("format error !"); } type = OPERATOR; operator(stack, c); break; case '(': type = START_PAREN; stack.push(c); break; case ')': if(type == OPERATOR){ throw new RuntimeException("format error !"); } type = END_PAREN; endParen(stack); break; } } } if(str.length() != 0){ postfix.add(str.toString()); } while(!stack.isEmpty()){ char operator = stack.pop(); if(operator == '('){ throw new RuntimeException("paren not paired !"); } postfix.add(operator + ""); } } /** * 公式结果 * @param variable 公式变量 * @return 结果 */ public double getResult(double... variable){ LinkedList<Double> stack = new LinkedList<Double>(); int varIndex = 0; for(String element : postfix){ char c = element.charAt(0); if(c >= 48 && c <= 57 || c == 46){ stack.push(Double.parseDouble(element)); }else if(c >= 97 && c <= 122){ stack.push(variable[varIndex]); varIndex++; }else{ double num2 = stack.pop(); double num1 = stack.pop(); double num; switch(c){ case '+': num = num1 + num2; break; case '-': num = num1 - num2; break; case '*': num = num1 * num2; break; case '/': num = num1 / num2; break; default: num = 0; } stack.push(num); } } if(stack.size() == 0){ return 0; }else{ return stack.pop(); } } /** * 处理操作符 * @param operator 操作符 */ private void operator(LinkedList<Character> stack, char operator){ int prior = priority.get(operator); while(!stack.isEmpty()){ char thisOperater = stack.pop(); if(thisOperater == '('){ stack.push(thisOperater); break; }else{ int thisPrior = priority.get(thisOperater); if(thisPrior < prior){ stack.push(thisOperater); break; }else{ postfix.add(thisOperater + ""); } } } stack.push(operator); } /** * 处理结束括号 */ private void endParen(LinkedList<Character> stack){ boolean startParen = false; while(!stack.isEmpty()){ char element = stack.pop(); if(element == '('){ startParen = true; break; }else{ postfix.add(element + ""); } } if(startParen == false){ throw new RuntimeException("paren not paired !"); } } public static void main(String[] args) { Formula formula = new Formula("3*(4+a)/6"); System.out.println(formula.getResult(5)); } }
参考了java数据结构和算法 第二版。但,加入了错误处理、变量等。
相关推荐
开源表达式解析器,开源表达式解析器开源表达式解析器开源表达式解析器
delphi 教你如何做表达式解析器 词法分析器 语法分析器
一个C#实现的简单表达式解析器,支持算符优先级、括号以及函数。 修正前一个上传版本存在的问题:算符优先级的错误。
表达式解析器源代码(可以计算各种函数),对编译原理理解有好处
数学公式解析器,提供源码,代码可集成到自己的系统中
实现+、-、*、/、%、<、>、=、、、>= 详细信息查看如下地址: http://blog.csdn.net/welliu/archive/2011/04/13/6320562.aspx
输入一个带参数的表达式,运算包括四则运算和c++中常用函数运算,三角函数、开放、幂运算等,输入完成后,再输入参数的值,可以计算出表达式的值
一个适用于 OA工作流系统的简单的公式解析器。 用于工作流中的简单逻辑判断,非常易用。 也可用在二次开发中,让最终用户可以简单的配置工作流的条件 详细请查阅 http://linliangyi2007.javaeye.com/blog/299897
MFC实现的简易计算器:用编译原理方法(词法分析和语法分析)对表达式进行解析,判断其合法性;并通过后缀表达式进行求值。
JavaScript公式解析器 fparser提供了一个Formula类,该类将包含数学公式(例如x*sin(PI*x/2) )的字符串解析为可评估的对象。 然后,可以为所有未知变量/函数提供值,并从公式中计算出数值。 有关示例应用程序,请...
表达式解析器类库 支持的数学运算: +,-,*,/,^,div,mod,() 支持的逻辑运算: not,and,or,xor,shl,shr 支持的数学函数(请参照Delphi中参数定义): abs,acos,asin,atan,ceil,cos,cosh,avg, cotan,floor,frac,max,min,...
C#写的表达式解析器,支持多种操作符 如加减乘除幂模,同时还支持正负、三角函数,随机值等函数,可以支持自己扩展操作符,同时能支持设置表达式中的变量.表达式使用的是逆波兰式(中缀表达式转换成的后缀表达式),非递归...
公式解析器,可解析数学公式,C语言代码,各种表达式,非常强大好用。
一个表达式解析器,,,支持 'ARCTAN','COS','DEG','PI','RAD','SIN', 'TAN','AND','FALSE','OR','TRUE','XOR', 'NOT','EXP','E','LN','LOG','SQR', 'SQRT','ABS','FRAC','INT','MAX','MIN', 'SGN','CSC','SEC','COT...
IK Expression是一个开源的(OpenSource),可扩展的(Extensible),基于java语言开发的一个超轻量级(Super lightweight)的公式化语言解析执行工具包。 IK ExpressionV2.X.X不依赖于任何第三方的java库。它做为一...
计算器Javascript的数学表达式解析器。 可在微信小程序中使用支持IE9 + 支持AMD / CommonJS 支持定制运营商支持自定义功能您可以使用util将数学表达式解析为反向波兰表示法或对其求值。例如,当解析1+2*3 ,您将获得...
IK Expression是一个开源的(OpenSource),可扩展的(Extensible),基于java语言开发的一个超轻量级(Super lightweight)的公式化语言解析执行工具包。 IK ExpressionV2.0.5不依赖于任何第三方的java库。它做为一...
数值表达式,可执行算术运算公式。 例如:(100 – 5) * 14/6 <br/>
','COS','DEG','PI','RAD','SIN', 'TAN','AND','FALSE','OR','TRUE','XOR', 'NOT','EXP','E','LN','LOG','SQR', 'SQRT','ABS','FRAC','INT','MAX','MIN', 'SGN','CSC','SEC','COT','SINH', 'COSH','TANH','CSCH','...
MTParser优雅简洁,提供LIB、COM组件、源代码三种引入方式,是用典型的C++风格编写的解析器,它引入多种设计模式,使用C++类接口继承的方式供扩展表达式句法操作符及函数,因而可扩展性和可维护性都很强,而且它的...