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();
}
}
分享到:
相关推荐
BigDecimal运算封装,里面封装了Integer和BigDecimal的"加减乘除法运算封装
BigDecimal运算Jar包。支持sin、cos、tan、asin、acos、atan、pow、sqrt、cbrt、root、log10、log、ln、exp、sinh、cosh、tanh、asinh、acosh、atanh、deg、rad
高精度JSBigDecimal运算,解决JS中BigDecimal运算和精度问题。
Java中BigInteger的数学运算,BigDecimal 加减乘除运算,Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大...
bigdecimal加减乘除运算
其中BigDecimal-all-last.min.js大小为:26KB GZIP压缩后7K,完全可以用于实际生产过程中。 简单例子: var a = new BigDecimal("1500"); var b = new BigDecimal("33"); alert(a.multiply(b)); alert&#...
本版中只有一个用于生产环境的文件:BigDecimal-all-last.min.js,大小为26K,如果WEB服务器打开GZIP压缩,可以减小至7K,如需完整版本请移步至:http://download.csdn.net/detail/aquaqu2009/4575230 简单用法: ...
下面小编就为大家带来一篇Java中BigDecimal的基本运算(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
build/BigDecimal-all-last.js build/BigDecimal-all-last.min.js build/preserved_multiline_comment_begin.closure.js build/preserved_multiline_comment_begin.yui.js build/preserved_mult
他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,例如银行...
bigdecimal加减乘除运算
今天小编就为大家分享一篇关于Java使用BigDecimal进行运算封装的实际案例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
java 代码 BigDecimal b1=new BigDecimal(...,由于浮点运算的原因,要慎用第三种方式,否则就会得到上面的结果。所以,改用 java 代码 assertEquals(bd.compareTo(new BigDecimal("0.15")),0); 之后,测试顺利通过了。
BigDecimal 使用方法小节:包含构造方法及和、差、商、积等运算方式
本篇文章主要介绍了【Java】BigDecimal实现加减乘除运算代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
主要介绍了如何使用BigDecimal进行精确运算,最后提供了一个工具类,该工具类提供加,减,乘,除运算
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。这篇文章主要介绍了Java BigDecimal使用指南针(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,...
是不是还在为多精度小数运算烦恼 这个满足你一切要求 项目中需要对金钱进行运算,为了使计算结果更准确,故使用bigDecimal工具来实现
BigDecimal计算,用于处理Java中的大的数据的运算
主要介绍了Java中使用BigDecimal进行精确运算的方法,非常不错,需要的朋友参考下