`
奥义之舞
  • 浏览: 281602 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java 字符串转换成算术表达式

    博客分类:
  • Java
 
阅读更多
今天遇到了一个需要将数据库中保存的表达式,替换其中的字符,并计算出值,java是不能直接计算的例如:
double d = (3+5-(2-4)*2)/24;没有问题

但是:遇到   "(3+5-(2-4)*2)/24" 字符串的格式,就不能使用了


java是无法解决,但是javaScript中有一个eval函数是可以执行的,所以,可以通过其他途径执行javaScript就可以做到,而ScriptEngine是java的一个javaScript实现类,所以就找到了方法,详细方法见下

public class MapJ {
	private String key;//替换的编号
	private String value;//值
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public MapJ(String key, String value) {
		super();
		this.key = key;
		this.value = value;
	}
	public MapJ() {
		super();
	}
	
}


//实现类
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JavaScript {
	ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    
    public Double getMathValue(List<MapJ> map,String option){
    	double d = 0;
		try {
			for(int i=0; i<map.size();i++){
				MapJ mapj = map.get(i);
				option = option.replaceAll(mapj.getKey(), mapj.getValue());
			}
			Object o = engine.eval(option);
			d = Double.parseDouble(o.toString());
		} catch (ScriptException e) {
			System.out.println("无法识别表达式");
			return null;
		}
		return d;
    }
}


//测试
import java.util.ArrayList;
import java.util.List;

public class JavaScriptTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		

		String sbt = "(B+D-(A-C)*A)/F";
		List<MapJ> all = new ArrayList<MapJ>();
		all.add(new MapJ("A","2"));
		all.add(new MapJ("B","3"));
		all.add(new MapJ("C","4"));
		all.add(new MapJ("D","5"));
		all.add(new MapJ("F","24"));
		JavaScript js = new JavaScript();
		Double d = js.getMathValue(all, sbt);
		if(d==null){
			System.out.println("                 无法计算这个表达式");
		}else{
			System.out.println(d*100+"%");
		}
	}

}



通过以上的方法即可实现此方法。
以上转载自:http://ruyuntao.iteye.com/blog/406935
----------------------------------------------------------------------------
下面是算法实现的:
package cn.anycall.test;

import java.math.BigDecimal;

public class TestSHU {

	/**  
     * 两个字符类型的小数进行相加为a+b;  
     *   
     * @param a  
     * @param b  
     * @return  
     */  
    public static String addBigDecimal(String a, String b) {   
        double a1 = Double.parseDouble(a);   
        double b1 = Double.parseDouble(b);   
        BigDecimal a2 = BigDecimal.valueOf(a1);   
        BigDecimal b2 = BigDecimal.valueOf(b1);   
        BigDecimal c2 = a2.add(b2);   
        String c1 = c2 + "";   
        return c1;   
    }  
    /**  
     * 两个字符类型的小数进行相减为a-b;  
     *   
     * @param a  
     * @param b  
     * @return  
     */  
    public static String reduceBigDecimal(String a, String b) {   
        double a1 = Double.parseDouble(a);   
        double b1 = Double.parseDouble(b);   
        BigDecimal a2 = BigDecimal.valueOf(a1);   
        BigDecimal b2 = BigDecimal.valueOf(b1);   
        BigDecimal c2 = a2.subtract(b2);   
        String c1 = c2 + "";   
        return c1;   
    }  
    /**  
     * 两个字符类型的数相乘 a*b=c;  
     *   
     * @param a  
     * @param b  
     * @return  
     */  
    public static String multipliedString(String a, String b) {   
        double a1 = Double.parseDouble(a);   
        double b1 = Double.parseDouble(b);   
        BigDecimal a2 = BigDecimal.valueOf(a1);   
        BigDecimal b2 = BigDecimal.valueOf(b1);   
        BigDecimal c2 = a2.multiply(b2);   
        String c1 = c2 + "";   
        return c1;   
    }  
    /**  
     * 两个字符类型的数相除 a/b=c;  
     *   
     * @param a  
     * @param b  
     * @return  
     */  
    public static String divideString(String a, String b) {   
        double a1 = Double.parseDouble(a);   
        double b1 = Double.parseDouble(b);   
        BigDecimal a2 = BigDecimal.valueOf(a1);   
        BigDecimal b2 = BigDecimal.valueOf(b1);   
        BigDecimal c2 = a2.divide(b2,a2.scale());   
        String c1 = c2 + "";   
        return c1;   
    }  

	public static String yunsuanjibie(String s) {
		String r = "";
		int p = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '*'
					|| s.charAt(i) == '/') {
				p++;
			}
		}
		String k[] = new String[2 * p + 1];
		int k1 = 0;
		int first = 0;
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '*'
					|| s.charAt(i) == '/') {
				k[k1] = s.substring(first, i);
				k1++;
				k[k1] = "" + s.charAt(i);
				k1++;
				first = i + 1;
			}
		}
		k[k1] = s.substring(first, s.length());
		int kp = p;
		while (kp > 0) {
			for (int i = 0; i < k.length; i++) {
				if (k[i].equals("*") || k[i].equals("/")) {
					int l;
					for (l = i - 1; l > -1; l--) {
						if (!(k[l].equals("p")))
							break;
					}
					int q;
					for (q = i + 1; q < k.length; q++) {
						if (!(k[l].equals("p")))
							break;
					}
					if (k[i].equals("*")) {
						k[i] = ""+ multipliedString(k[l],k[q]);
						k[l] = "p";
						k[q] = "p";
						kp--;
					} else {
						k[i] = ""+divideString(k[l],k[q]);
						k[l] = "p";
						k[q] = "p";
						kp--;
					}
					break;
				}
			}
			for (int i = 0; i < 2 * p + 1; i++) {
				if (k[i].equals("+") || k[i].equals("-")) {
					int l;
					for (l = i - 1; l > -1; l--) {
						if (!(k[l].equals("p")))
							break;
					}
					int q;
					for (q = i + 1; q < k.length; q++) {
						if (!(k[q].equals("p")))
							break;
					}
					if (k[i].equals("+")) {
						k[i] = ""+addBigDecimal(k[l],k[q]);
						k[l] = "p";
						k[q] = "p";
						kp--;
					} else {
						k[i] = ""+reduceBigDecimal(k[l],k[q]);
						k[l] = "p";
						k[q] = "p";
						kp--;
					}
					break;
				}
			}
			for (int i = 0; i < k.length; i++) {
				if (!(k[i].equals("p"))) {
					r = k[i];
					break;
				}
			}
		}
		return r;
	}

	public static void sizeyunsuan(String s) {
		while (true) {
			int first = 0;
			int last = 0;
			for (int i = 0; i < s.length(); i++) {
				if (s.charAt(i) == '(')
					first = i;
				if (s.charAt(i) == ')') {
					last = i;
					break;
				}
			}
			if (last == 0) {
				System.out.println(yunsuanjibie(s));
				return;
			} else {
				String s1 = s.substring(0, first);
				String s2 = s.substring(first + 1, last);
				String s3 = s.substring(last + 1, s.length());
				s = s1 + yunsuanjibie(s2) + s3;
			}
		}
	}

	public static void main(String[] args) {
		String s = "1.4+2*32/(3-2.1)";
		sizeyunsuan(s);
	}

}


转载自:http://yafei.iteye.com/blog/725582
分享到:
评论
1 楼 zhou85xin 2014-12-04  
option = option.replaceAll(mapj.getKey(), mapj.getValue());

这个就不对,map中key如果contains,很容易就替换错了

相关推荐

    JAVA上百实例源码以及开源项目

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    JAVA上百实例源码以及开源项目源代码

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    MathParser Java - Math Parser library:Java数学解析器-开源

    该项目提供了一个数学解析器,用于将简单的字符串表达式转换为结果,可以将其管理以用于其他计算(全部使用Java)。 使用几行代码,您将能够高效地解析复杂的算术表达式。 该库由Dijkstra的Shutting-yard算法提供...

    java开源包4

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包101

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包11

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包6

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包9

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包8

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包10

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包5

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包1

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java开源包3

    J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-OSGi R-OSGi 是一套适用于任意满足 OSGi 架构的分布式通讯组件。它以 jar 的形式发布,部署容易,使用...

    java初学者必看

    5.1.3 StringBuffer创建字符串 5.2 连接字符串 5.2.1 与字符串的连接 5.2.2 与其他数据类型的连接 5.3 String字符串操作 5.3.1 基本操作 5.3.2 比较 5.3.3 转化 5.3.4 查找 5.3.5 截取拆分 5.3.6 替换或...

    java基础知识

    六 转义符 字符串长度加 双引号 就在 后边加 &quot; 如果要加 单引号 就在 后边加 &quot; 43 七 字符串常用的提取和查询的方法 43 八 练习: 44 Java知识点总结 48 一 布尔类型 48 二 强转 48 三 运算符: 49 1 ...

    Java实验报告(5).doc

    使用堆栈,将中缀算术表达式转换成后缀表达式。 a) 表达式中只有+、-、×,/,%,(,)六种运算符 b) 变量名为以英文字母开头的字母数字串 c) 表达式中可以出现不带符号的常数 d) 适当判断表达式中的语法错误 e)...

    java范例开发大全源代码

     实例102 算术表达式求值器 129  实例103 字符串对齐调整器 137  实例104 字符串的加密 139  实例105 使用正则表达式验证电话号码的格式 141  6.2 字符串缓存类StringBuffer 143  实例106 创建字符...

    Java范例开发大全 (源程序)

     实例102 算术表达式求值器 129  实例103 字符串对齐调整器 137  实例104 字符串的加密 139  实例105 使用正则表达式验证电话号码的格式 141  6.2 字符串缓存类StringBuffer 143  实例106 创建字符串缓存...

Global site tag (gtag.js) - Google Analytics