关闭

java字符串数学公式运算

标签: javastringnullexceptionclassinteger
8998人阅读 评论(1) 收藏 举报
//由于网络限制禁止上传,因此在此提供源码,jar自己进行制作
/**
  pulbic static void main(String[]args){
     RunStringReg.cacComplex("1+1*2+(10-(2*(5-3)*(2-1))-4)+10/(5-0)");
  }
  思路整理:
  1.判断表达式中是否存在括号,如果存在,则提取括号中的表达式,进行计算(见步骤2),计算结束后,再次执行步骤1;如果不存在则直接执行步骤2.
  2.判断是否有乘除运算,如果有,则先执行乘除运算,执行完毕后再次执行步骤2;如果不存在则直接执行加减运算返回结果。
   参考: sghitxia
**/

ProgramService.java

package com.goma.runstringregex;

import java.math.BigDecimal;
/**
* DESC:采用BigDecimal进行运算的简单封装<BR>
* @author Goma(OMA1989@YEAH.NET)
*
*/
public class ProgramService
{
    /**
     * param:String
     * 将Null转为Zero
     * @return "0"
     */
    private String null2zero(String str)
    {
        if (str == null || "".equals(str))
        {
            str = "0";
        }
        return str;
    }

    /**
     * 提供精确的加法运算
     * @param v1 被加
     * @param v2 加数
     * @return 两个参数的和
     */
    public String add(String v1, String v2)
    {
        v1 = null2zero(v1);
        v2 = null2zero(v2);
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).toString();
    }

    /**
     * 提供精确的加法运算
     * @param params 
     * @return 两个参数的和
     */
    public String add2(String[] params)
    {
        String v0 = null2zero(params[0]);
        BigDecimal b0 = new BigDecimal(v0);
        for (int i = 1; i < params.length; i++)
        {
            String v1 = null2zero(params[i]);
            b0 = b0.add(new BigDecimal(v1));
        }
        return b0.toString();
    }

    /**
     * 提供精确的减法运算
     * @param v1 被减
     * @param v2 减数
     * @return 两个参数的差
     */
    public String sub(String v1, String v2)
    {
        v1 = null2zero(v1);
        v2 = null2zero(v2);
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).toString();
    }

    /**
     * 提供精确的减法运算
     * @param params
     * @return 传入参数 下标为0,与其他参数的差
     */
    public String sub2(String[] params)
    {
        String v0 = null2zero(params[0]);
        BigDecimal b = new BigDecimal(v0);
        for (int i = 1; i < params.length; i++)
        {
            String v1 = null2zero(params[i]);
            b = b.subtract(new BigDecimal(v1));
        }
        return b.toString();
    }

    /**
     * 提供精确的乘法运算
     * @param v1 被乘
     * @param v2 乘数
     * @return 两个参数的积
     */
    public String mul(String v1, String v2)
    {
        v1 = null2zero(v1);
        v2 = null2zero(v2);
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).toString();
    }

    /**
     * DESC:提供精确的乘法运算
     * @param params
     * @return 传入参数的积
     */
    public String mul2(String[] params)
    {
        String v0 = null2zero(params[0]);
        BigDecimal b1 = new BigDecimal(v0);
        for (int i = 1; i < params.length; i++)
        {
            String v1 = null2zero(params[i]);
            b1 = b1.multiply(new BigDecimal(v1));
        }
        return b1.toString();
    }

    /**
     * 提供(相对)精确的除法运算 当发生除不尽的情况时,由scale参数
     * 定精度,以后的数字四舍五入
     * @param v1 被除
     * @param v2 除数
     * @param scale 表示表示 精确到小数点以后几位
     * @return 两个参数的商
     */
    public String div(String v1, String v2, int scale)
    {
        if (scale < 0)
        {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        v1 = null2zero(v1);
        v2 = null2zero(v2);
        if ("0".equals(v2)||"0.00".equals(v2))
        {
            return "0";
        }
        else
        {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
        }
    }

}



package com.goma.runstringregex;

/**
* DESC:字符串表达式计算<BR>
* @author Goma(OMA1989@YEAH.NET)<br>
*/
public class RunStringReg {
    private static ProgramService ps = new ProgramService();
/**
* DESC:判断表达式是否有括号,有括号,则先计算括号内的表达式,无则直接运算结果。
* @param str
* @return 运算结果
*/
public static String cacComplex(String str) {
if (str.equals(""))
return "0";
int has = str.indexOf("[");
int have = str.indexOf("{");
System.out.println("RUN BEFORE:"+str);
if(has!=-1||have!=-1){
str = str.replaceAll("[\\[\\{]", "(").replaceAll("[\\]\\}]", ")");//将字符串中的"{}"、"[]"替换成"()"
System.out.println("TURN '{,[':" + str);
}
int cl = str.lastIndexOf('(');//判断字符串中是否存在"("
if (cl == -1)
return cac(str);//不存在"("直接处理运行表达式
int cr = str.indexOf(')', cl);
String left = str.substring(0, cl);
String right = str.substring(cr + 1);
String middle = str.substring(cl + 1, cr);//如果存在"("提取括号中的表达式
return cacComplex(left + cac(middle) + right);
}

/**
* DESC:计算表达式,判断是否存在乘除运算,存在则先执行乘除运算,然后执行加减运算,返回运算结果;
* 不存在,直接运行加减运算,返回运算结果。
* @param str
* @return 运算结果
*/
private static String cac(String str) {
if (str.equals(""))
return "0";
int ml = str.indexOf('*');
int dl = str.indexOf('/');
if (ml == -1 && dl == -1) {
return cacNoMD(str);
}
int index = ml == -1 ? dl : ml;
String left = str.substring(0, index);
String m1 = lastNumber(left);
left = left.substring(0, left.length() - m1.length());
String right = str.substring(index + 1);
String m2 = firstNumber(right);
right = right.substring(m2.length());
String tmp = "0";
if (index == ml) {
tmp = ps.mul(m1, m2);
} else if (index == dl) {
tmp = ps.div(m1, m2, 4);
}
return cac(left + tmp + right);
}
    /**
     * Description:获得表达式的最后一位数字
     * @param str
     * @return 表达式最后一位数字
     */
private static String lastNumber(String str) {
StringBuilder sb = new StringBuilder();
for (int i = str.length() - 1; i >= 0; i--) {
char c = str.charAt(i);
if (!Character.isDigit(c) && c != '.')
break;
sb.append(c);
}
return sb.reverse().toString();
}

/**
* DESC:获得表达式的的一位数字
* @param str
* @return 表达式的第一位数字
*/
private static String firstNumber(String str) {
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray()) {
if (!Character.isDigit(c) && c != '.')
break;
sb.append(c);
}
return sb.toString();
}

/**
* DESC:加减运算表达式计算
* @param str
* @return 计算结果
*/
private static String cacNoMD(String str) {
String ret = "0";
StringBuilder sb = new StringBuilder();
char sign = '+';
for (char c : (str + "+").toCharArray()) {
if (!Character.isDigit(c) && c != '.') {
if (sb.length() == 0)
continue;
if (sign == '+') {
ret = ps.add(ret, sb.toString());
} else {
ret = ps.sub(ret, sb.toString());
}
sb = new StringBuilder();
sign = c;
} else {
sb.append(c);
}
}
return ret;
}

}
 
 
jdk1.6 
用 javax.script.ScriptEngine 的Object eval(String script)方法可以计算字符串表达式的值
具体可查考API和以下demo
----------------------------------------------------------------
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class T{
ScriptEngine jse;
public T(String s){
jse = new ScriptEngineManager().getEngineByName("JavaScript");
try{
Boolean res = (Boolean)jse.eval(s);
System.out.println(res);
}catch(Exception t){}
}
}
 
 
0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:466240次
    • 积分:1199
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:28篇
    • 译文:2篇
    • 评论:44条
    最新评论