`
kevin_wanwei
  • 浏览: 117572 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java 解析数学表达式

阅读更多

数学表达式解析工具类:

支持负数运算,

多层括号嵌套运算

 

采用堆栈实现,实现步骤:

(1)除去表达式中所有空白

(2)提取表达式运算符合

(3)依据运算符合,将表达式转化为一个数组

(4)对这个数组进行数学运算优先级转化,生成一个新数组的

(5)最后对这个数组进行运算,得到结果

注:具体算法细节请查看代码。

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package autotest.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Pattern;

import autotest.util.StringUtils;

/**
 * 支持加减乘法运算
 * @author Administrator
 */
public  class ExpressionResolver {

    private final static Map<String,Integer> SERT=new HashMap<String,Integer>();
    
    static{
        SERT.put("+", 1);
        SERT.put("-", 1);
        SERT.put("*", 2);
        SERT.put("/", 2);
        
        SERT.put("(", 3);
        SERT.put(")", 3);
    }
    /**
     * 转换有负号表达式-3+2 转换为 (0-3)+2
     * 2-3不转
     * (-3)+2 ==>((0-3))+2
     * @param exp
     * @return
     */
    private static String transfrom(String exp){
    	exp=StringUtils.trimAllSpace(exp);
    	return exp.replaceAll("(\\(|^)-(\\d*)", "$1(0-$2)");
    }
    /**
     * 解析表达式
     * @param exp
     * @return
     */
    private static List<String> resolveExpr(String exp){
        String opert=exp.replaceAll("\\d*", "");
        List<String> list=new ArrayList<String>();
        int pidx=-1;
        for(int i=0;i<opert.length();i++){
            String p=opert.substring(i, i+1);
            pidx=exp.indexOf(p);
            if(exp.substring(0,pidx).trim().length()!=0){
                list.add(exp.substring(0, pidx));
            }
            list.add(exp.substring(pidx, pidx+1));
            exp=exp.substring(pidx+1);
        }
        if(exp.length()>0){
            list.add(exp);
        }
        return list;
    }
    /**
     * 转为计算机可以识别的表达式
     * @param list
     * @return
     */
    private static String[] transfrom(List<String> list){
        Stack<Sign> op=new Stack<Sign>();
        Stack<String> data=new Stack<String>();
      
        Iterator<String> it=list.iterator();
        int p1=0,p2=0,add=0;

        while(it.hasNext()){
            String e=it.next();
            if(SERT.containsKey(e)){
                if(op.size()>0){
                    p1=op.peek().getWeight();
                }
                p2=SERT.get(e)+add;
                if(e.equals("(")){
                	add+=SERT.get(e);
                	continue;
                }
                if(e.equals(")")){
                	add-=SERT.get(e);
                	continue;
                }
                while(p2<=p1){
                    data.push(op.pop().getSign());
                    if(op.size()==0){
                        break;
                    }
                    p1=op.peek().getWeight();
                }
                op.push(new Sign(e,p2));
            }else{
                data.push(e);
            }
        }
        while(op.size()>0){
            data.push(op.pop().getSign());
        }
        String[] result=new String[data.size()];
        for(int i=0;i<result.length;i++){
            result[result.length-i-1]=data.pop();
        }
        return result;
    }
    /**
     * 计算表达式值
     * @param exp
     * @param duckSqls
     * @return
     */
    public static Object getExp(String exp,List<DuckSQL> duckSqls)throws Exception{
//        if(!StringUtils.isValidateStr(exp) || duckSqls==null || duckSqls.size()<=0){
//            return null;
//        }
    	exp=transfrom(exp);
        String[] strs=transfrom(resolveExpr(exp));
        Stack<Object> expstack=new Stack<Object>();
        for(int i=0;i<strs.length;i++){
            String str=strs[i];
            if(SERT.containsKey(str)){
            	expstack.push(calc(expstack.pop(),expstack.pop(),str,duckSqls));
            }else{
                expstack.push(str);
            }
        }
        if(expstack.size()==1){
            return expstack.pop();
        }else{
            return "ERR";
        }
    }
    /**
     * 计算结果
     * @param s1
     * @param s2
     * @param op
     * @return
     */
    private static Object calc(Object s1,Object s2,String op,List<DuckSQL> duckSqls)throws Exception{
    	Double d1=null,d2=null;
        if(s1 instanceof String){
        	d1=Double.parseDouble((String)s1);//getValue((String)s1,duckSqls);
        }else{
        	d1=(Double)s1;;
        }
        if(s2 instanceof String){
        	d2=Double.parseDouble((String)s2);;
        }else{
        	d2=(Double)s2;
        }
        if(op.equals("-")){
        	return d2-d1;
        }else if(op.equals("+")){
        	return d2+d1;
        }else if(op.equals("*")){
        	return d2*d1;
        }else if(op.equals("/")){
        	return d2/d1;
        }else{
        	throw new Exception("表达式中运算符["+op+"]是不合法的");
        }
    }

    private static Double getValue(String str,List<DuckSQL> duckSqls)throws Exception{
    	if(!Pattern.matches("\\d{2}", str)){
    		throw new Exception("表达式中含有不合法的式子["+str+"]");
    	}
    	Object obj = duckSqls.get(Integer.parseInt(str.substring(0, 1))-1).getRsdata()[Integer.parseInt(str.substring(1, 2))-1];
		
    	if(obj instanceof Number){
    		return ((Number)obj).doubleValue();
    	}else{
    		throw new Exception("["+str+"]式子对应结果不是数据类型不可以加减乘法运算");
    	}
    }

    public static void  main(String[] args)throws Exception{
//        List<String> list=resolveExpr("(12+13)*14+15");
//
//        String[] strs=transfrom(list);
//        for(String str:strs){
//            System.out.println(str);
//        }

    	System.out.println(getExp("-3+2*(-5)+6+(-4)*7*(-9)*(2-3)",null));
    	
    //	System.out.println("-3+2*(-5)+6+(-4)*7*(-9)*(2-3)".replaceAll("(\\(|^)-(\\d*)", "$1(0-$2)"));
    	
    }
}

 

分享到:
评论
1 楼 foreverlove99 2012-02-15  
这个例子好像不全啊。。。。

相关推荐

    数学表达式解析器java语言描述

    总之,数学表达式解析器Java语言描述涉及到了词法分析、语法分析、抽象语法树构建、数据结构使用和错误处理等多个方面。Calculator.jar库提供了这样的功能,而解析器.jpg文件可能有助于可视化和理解解析过程。对于...

    Java数学表达式计算(Expression Evaluator)

    在Java编程中,处理数学表达式的计算是一项常见的任务,尤其在需要动态计算或者解析用户输入时。本主题将深入探讨如何在Java中实现一个数学表达式计算器,这通常被称为"Expression Evaluator"。我们将讨论相关的技术...

    Java 数学表达式解析器

    可以支持复杂的数学表达式(常量、变量、带括号)的计算 如123 + (a * 456)/c - (d + 789) 输入变量值,展示计算步骤和结果 目前支持+ - * / 幂 cos等操作 操作符可方便扩展

    java数学表达式计算程序设计报告

    在这个项目中,Java 被用来编写数学表达式计算程序,展示了其在软件开发中的灵活性。 2. 知识点:课程设计 该项目作为课程设计的一部分,旨在让学生应用所学的 Java 语言知识,通过实践提高编程技能和问题解决能力...

    java 计算数学表达式

    在Java编程语言中,计算数学表达式是一项常见的需求,它涉及到字符串解析、语法分析和运算符优先级处理等多个环节。`jeval-0.9.4`是一个Java库,专门用于解析和评估数学表达式。这个库使得开发人员能够轻松地在程序...

    计算器【解析数学表达式】

    首先,递归算法在解析数学表达式中扮演着至关重要的角色。递归是一种解决问题的方法,它通过将问题分解为更小的子问题来解决原问题。在这个计算器中,可能使用的递归策略是对表达式进行分治,将复杂的数学表达式分解...

    Java计算数学表达式代码详解

    这个过程涉及到的算法和数据结构是理解Java计算数学表达式的基础,对于开发计算工具或解析数学公式的应用非常有用。在实际编程中,可以使用已有的库,如Apache Commons Math或Java 8的`ScriptEngine`接口,来简化这...

    java字符串数学表达式(含括号)计算值

    代码均为自己设计所写,分享一下。 字符串数学表达式(含括号)计算值 如: "31+3*3-20/2*5+40/8+4*5" ((2*(19-13*(1+2)/39)/6+4)-5)/5+((2+3)*2-5)

    输入字符串数学表达式自动编译成数学表达式

    总的来说,将字符串数学表达式编译成可计算的表达式是一项涉及解析技术、符号计算和编程技能的综合任务,它在许多科学和工程领域都有着广泛的应用。理解并掌握这一技术,能帮助我们更好地开发和使用复杂的数学计算...

    Java表达式语法解析库 parboiled

    Java表达式语法解析库Parboiled是一个强大的工具,用于在Java平台上构建自定义的解析器。这个库由Sirthias开发,它引入了一种新的、更简洁的方式来编写解析规则,使得解析器的创建过程变得更加简单和高效。Parboiled...

    java表达式解析,附加

    在Java编程语言中,表达式解析是程序设计中的一个关键环节,它涉及到将人类可读的数学或逻辑表达式转化为计算机能理解的形式。这个过程通常由编译器或解释器执行,以便执行相应的计算或操作。这篇博客文章,虽然链接...

    java正则实现解析算术表达式 (仅限+-*/和括号)

    java正则实现解析算术表达式 (仅限+-*/和括号)

    利用Java动态编译计算数学表达式

    前几天要做一个计算数学表达式的题目,本来计划使用解析表达式的方法来解析各种数学表达式,然后再动态计算表达式的值.后来考虑到这样编程的任务很重,时间有限 后来在网上搜搜,看到使用动态编译并使用反射机制 ,这样...

    Java算术表达式计算类库 ExpressionJ

    ExpressionJ为Java开发者提供了一个强大而灵活的工具,用于处理和计算数学表达式。无论是简单的加减乘除,还是复杂的数学函数,甚至是自定义的运算规则,它都能轻松应对。对于需要进行动态计算的项目,ExpressionJ是...

    java解析表达式JEXL实现办法

    Java解析表达式是一个常见的需求,特别是在需要动态计算或者执行用户输入的简单脚本时。JEXL(Java Expression Language)是Apache Commons项目提供的一种轻量级的表达式语言,它允许我们在Java应用程序中方便地执行...

    java 公式解析源码

    总的来说,Java公式解析源码是实现动态计算和自定义逻辑的关键工具,其核心在于理解和处理数学表达式的语法和语义。通过理解并使用这些源码,开发者可以构建出能够灵活处理各种计算场景的应用。

    mep4j:数学表达式解析器4 Java-开源

    数学表达式解析器4 Java MEP4J是用于Java的高性能数学表达式字符串解析器(J2SE&gt; = 5)。 将其与同类库的性能进行比较,并让我知道您的经验。 该库管理5个运算符(+,-,/,%,*)以及以下功能:-“ abs”-“ cos”...

    Java计算数学表达式的结果的jar包(bsh-2.0b4.jar)

    Java计算数学表达式的结果主要依赖于像bsh(BeanShell)这样的库,BeanShell是一个小型、开源的Java脚本环境,它可以动态执行Java代码并提供一个交互式的解释器。在这个场景中,`bsh-2.0b4.jar` 是BeanShell的一个...

    纯java代码 一个计算数学表达式的程序设计

    在Java编程领域,设计一个能够计算数学表达式的程序是一项常见的任务,这有助于理解和掌握核心的编程概念,如语法解析、运算符优先级处理以及变量管理等。本项目以"纯java代码"实现了这样一个计算器,专注于计算数学...

    Java 图形界面化实现计算数学表达式

    5. **表达式解析**:Java程序需要能够正确解析用户输入的数学表达式。这可能涉及正则表达式用于验证输入格式,或者使用字符串分割和栈数据结构来实现一个简单的解析器,处理运算符优先级和括号。 6. **异常处理**:...

Global site tag (gtag.js) - Google Analytics