精华内容
下载资源
问答
  • Java字符串转换成算术表达式计算并输出结果,通过这个工具可以直接对字符串形式算术表达式进行运算,并且使用非常简单。 这个工具中包含两个 Calculator 和 ArithHelper Calculator 代码如下: import ...

    Java字符串转换成算术表达式计算并输出结果,通过这个工具可以直接对字符串形式的算术表达式进行运算,并且使用非常简单。

    这个工具中包含两个类 Calculator 和 ArithHelper

    Calculator 代码如下:

    import java.util.Collections;
    import java.util.Stack;
    
    /**
     *  算数表达式求值 
     *  直接调用Calculator的类方法conversion() 
     *  传入算数表达式,将返回一个浮点值结果
     *  如果计算过程错误,将返回一个NaN
     */
    public class Calculator {
        private Stack<String> postfixStack = new Stack<String>();// 后缀式栈
        private Stack<Character> opStack = new Stack<Character>();// 运算符栈
        private int[] operatPriority = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };// 运用运算符ASCII码-40做索引的运算符优先级
    
        public static double conversion(String expression) {
            double result = 0;
            Calculator cal = new Calculator();
            try {
                expression = transform(expression);
                result = cal.calculate(expression);
            } catch (Exception e) {
                // e.printStackTrace();
                // 运算错误返回NaN
                return 0.0 / 0.0;
            }
            // return new String().valueOf(result);
            return result;
        }
    
        /**
         * 将表达式中负数的符号更改
         *
         * @param expression
         *            例如-2+-1*(-3E-2)-(-1) 被转为 ~2+~1*(~3E~2)-(~1)
         * @return
         */
        private static String transform(String expression) {
            char[] arr = expression.toCharArray();
            for (int i = 0; i < arr.length; i++) {
                if (arr[i] == '-') {
                    if (i == 0) {
                        arr[i] = '~';
                    } else {
                        char c = arr[i - 1];
                        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
                            arr[i] = '~';
                        }
                    }
                }
            }
            if(arr[0]=='~'||arr[1]=='('){
                arr[0]='-';
                return "0"+new String(arr);
            }else{
                return new String(arr);
            }
        }
    
        /**
         * 按照给定的表达式计算
         *
         * @param expression
         *            要计算的表达式例如:5+12*(3+5)/7
         * @return
         */
        public double calculate(String expression) {
            Stack<String> resultStack = new Stack<String>();
            prepare(expression);
            Collections.reverse(postfixStack);// 将后缀式栈反转
            String firstValue, secondValue, currentValue;// 参与计算的第一个值,第二个值和算术运算符
            while (!postfixStack.isEmpty()) {
                currentValue = postfixStack.pop();
                if (!isOperator(currentValue.charAt(0))) {// 如果不是运算符则存入操作数栈中
                    currentValue = currentValue.replace("~", "-");
                    resultStack.push(currentValue);
                } else {// 如果是运算符则从操作数栈中取两个值和该数值一起参与运算
                    secondValue = resultStack.pop();
                    firstValue = resultStack.pop();
    
                    // 将负数标记符改为负号
                    firstValue = firstValue.replace("~", "-");
                    secondValue = secondValue.replace("~", "-");
    
                    String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
                    resultStack.push(tempResult);
                }
            }
                return Double.valueOf(resultStack.pop());
        }
    
        /**
         * 数据准备阶段将表达式转换成为后缀式栈
         * 
         * @param expression
         */
        private void prepare(String expression) {
            opStack.push(',');// 运算符放入栈底元素逗号,此符号优先级最低
            char[] arr = expression.toCharArray();
            int currentIndex = 0;// 当前字符的位置
            int count = 0;// 上次算术运算符到本次算术运算符的字符的长度便于或者之间的数值
            char currentOp, peekOp;// 当前操作符和栈顶操作符
            for (int i = 0; i < arr.length; i++) {
                currentOp = arr[i];
                if (isOperator(currentOp)) {// 如果当前字符是运算符
                    if (count > 0) {
                        postfixStack.push(new String(arr, currentIndex, count));// 取两个运算符之间的数字
                    }
                    peekOp = opStack.peek();
                    if (currentOp == ')') {// 遇到反括号则将运算符栈中的元素移除到后缀式栈中直到遇到左括号
                        while (opStack.peek() != '(') {
                            postfixStack.push(String.valueOf(opStack.pop()));
                        }
                        opStack.pop();
                    } else {
                        while (currentOp != '(' && peekOp != ',' && compare(currentOp, peekOp)) {
                            postfixStack.push(String.valueOf(opStack.pop()));
                            peekOp = opStack.peek();
                        }
                        opStack.push(currentOp);
                    }
                    count = 0;
                    currentIndex = i + 1;
                } else {
                    count++;
                }
            }
            if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {// 最后一个字符不是括号或者其他运算符的则加入后缀式栈中
                postfixStack.push(new String(arr, currentIndex, count));
            }
    
            while (opStack.peek() != ',') {
                postfixStack.push(String.valueOf(opStack.pop()));// 将操作符栈中的剩余的元素添加到后缀式栈中
            }
        }
    
        /**
         * 判断是否为算术符号
         *
         * @param c
         * @return
         */
        private boolean isOperator(char c) {
            return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
        }
    
        /**
         * 利用ASCII码-40做下标去算术符号优先级
         *
         * @param cur
         * @param peek
         * @return
         */
        public boolean compare(char cur, char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低
            boolean result = false;
            if (operatPriority[(peek) - 40] >= operatPriority[(cur) - 40]) {
                result = true;
            }
            return result;
        }
    
        /**
         * 按照给定的算术运算符做计算
         *
         * @param firstValue
         * @param secondValue
         * @param currentOp
         * @return
         */
        private String calculate(String firstValue, String secondValue, char currentOp) {
            String result = "";
            switch (currentOp) {
            case '+':
                result = String.valueOf(ArithHelper.add(firstValue, secondValue));
                break;
            case '-':
                result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
                break;
            case '*':
                result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
                break;
            case '/':
                result = String.valueOf(ArithHelper.div(firstValue, secondValue));
                break;
            }
            return result;
        }
    }

    ArithHelper 代码如下:

    public class ArithHelper {
    
        // 默认除法运算精度
        private static final int DEF_DIV_SCALE = 16;
    
        // 这个类不能实例化
        private ArithHelper() {
        }
    
        /**
         * 提供精确的加法运算。
         *
         * @param v1 被加数
         * @param v2 加数
         * @return 两个参数的和
         */
    
        public static double add(double v1, double v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
            java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
            return b1.add(b2).doubleValue();
        }
    
        public static double add(String v1, String v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
            java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
            return b1.add(b2).doubleValue();
        }
    
        /**
         * 提供精确的减法运算。
         *
         * @param v1 被减数
         * @param v2 减数
         * @return 两个参数的差
         */
    
        public static double sub(double v1, double v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
            java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
            return b1.subtract(b2).doubleValue();
        }
    
        public static double sub(String v1, String v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
            java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
            return b1.subtract(b2).doubleValue();
        }
    
        /**
         * 提供精确的乘法运算。
         *
         * @param v1
         *            被乘数
         * @param v2
         *            乘数
         * @return 两个参数的积
         */
    
        public static double mul(double v1, double v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
            java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
            return b1.multiply(b2).doubleValue();
        }
    
        public static double mul(String v1, String v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
            java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
            return b1.multiply(b2).doubleValue();
        }
    
        /**
         * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
         *
         * @param v1
         *            被除数
         * @param v2
         *            除数
         * @return 两个参数的商
         */
    
        public static double div(double v1, double v2) {
            return div(v1, v2, DEF_DIV_SCALE);
        }
    
        public static double div(String v1, String v2) {
            java.math.BigDecimal b1 = new java.math.BigDecimal(v1);
            java.math.BigDecimal b2 = new java.math.BigDecimal(v2);
            return b1.divide(b2, DEF_DIV_SCALE, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    
        /**
         * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
         *
         * @param v1 被除数
         * @param v2 除数
         * @param scale 表示表示需要精确到小数点以后几位。
         * @return 两个参数的商
         */
    
        public static double div(double v1, double v2, int scale) {
            if (scale < 0) {
                throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
            }
            java.math.BigDecimal b1 = new java.math.BigDecimal(Double.toString(v1));
            java.math.BigDecimal b2 = new java.math.BigDecimal(Double.toString(v2));
            return b1.divide(b2, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    
        /**
         * 提供精确的小数位四舍五入处理。
         *
         * @param v 需要四舍五入的数字
         * @param scale 小数点后保留几位
         * @return 四舍五入后的结果
         */
    
        public static double round(double v, int scale) {
            if (scale < 0) {
                throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
            }
            java.math.BigDecimal b = new java.math.BigDecimal(Double.toString(v));
            java.math.BigDecimal one = new java.math.BigDecimal("1");
            return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    
        public static double round(String v, int scale) {
            if (scale < 0) {
                throw new IllegalArgumentException("The   scale   must   be   a   positive   integer   or   zero");
            }
            java.math.BigDecimal b = new java.math.BigDecimal(v);
            java.math.BigDecimal one = new java.math.BigDecimal("1");
            return b.divide(one, scale, java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    }

    使用时调用 Calculator 类的 conversion()方法,并传入算术表达式参数,即可返回一个 Double 类型的值。

    使用示例:

     1 public class MathTest {
     2 
     3      public static void main(String[] args) {
     4      String expression = "(0*1--3)-5/-4-(3*(-2.13))";
     5      double result = Calculator.conversion(expression);
     6      System.out.println(expression + " = " + result);
     7      System.out.println();
     8      }
     9      
    10 }

    控制台输出:

    1

    (0*1--3)-5/-4-(3*(-2.13)) = 10.64

     

    展开全文
  • 以前写了一个java的正规表达式的java工具类,分享一下,有用到的欢迎下载使用。 如果你有常用的定义好的,且测试通过的正规表达式,欢迎跟贴,也让我享用一下 . 类中用到了 jakarta-oro-2.0.jar 包,请大家自己在 ...
  • java随机数

    2012-11-13 14:39:13
    1.java.lang.Math.random() 在所有其他语言中,生成随机数就像是使用Math工具类,如abs, pow, floor, sqrt和其他数学函数。大多数人通过书籍、教程和课程来了解这个类。一个简单例子:从0.0到1.0之间可以生成一个...
  • java范例开发大全

    2013-03-08 20:06:54
    11.1 数学Math 315 实例186 求圆周率∏值 315 实例187 求对数值 316 实例188 使用取整函数 317 11.2 Random类的使用 318 实例189 随机数 319 实例190 验证码 322 11.3 Date和Calendar 324 实例191 使用Date...
  • java范例开发大全源代码

    热门讨论 2011-10-30 23:31:51
     11.1 数学Math 315  实例186 求圆周率∏值 315  实例187 求对数值 316  实例188 使用取整函数 317  11.2 Random类的使用 318  实例189 随机数 319  实例190 验证码 322  11.3 Date和...
  • Java范例开发大全 (源程序)

    热门讨论 2011-04-27 07:47:22
     11.1 数学Math 315  实例186 求圆周率∏值 315  实例187 求对数值 316  实例188 使用取整函数 317  11.2 Random类的使用 318  实例189 随机数 319  实例190 验证码 322  11.3 Date和Calendar ...
  • Java范例开发大全(全书源程序)

    热门讨论 2013-04-05 11:50:26
    11.1 数学Math 315 实例186 求圆周率∏值 315 实例187 求对数值 316 实例188 使用取整函数 317 11.2 Random类的使用 318 实例189 随机数 319 实例190 验证码 322 11.3 Date和Calendar 324 实例191 ...
  • 《数据结构与算法分析:Java语言描述(第2版)》是国外数据结构与算法分析方面经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据方法)和算法分析(对算法运行时间估计)。...
  • 对数据的运算与处理是贯彻人类文明与历史的一个永恒的话题,从远古时代开始,我们的祖先就借助算盘等简单的工具进行数学计算,此后机械式计算器日益蓬勃地发展起来。自1946年世界上第一台电子计算机ENIAC诞生以来,...
  • 新版本的MATLAB语言是基于最为流行的C++语言基础上的,因此语法特征与C++语言极为相似,而且更加简单,更加符合科技人员对数学表达式的书写格式。使之更利于非计算机专业的科技人员使用。而且这种语言可移植性好、可...
  • Chaste:开放源代码C++库,用于为生理学和生物学开发的数学模型的计算仿真。 libsequence:用于表示和分析群体遗传学数据C++库。 SeqAn:专注于生物数据序列分析算法和数据结构。 Vcflib :用于解析和...
  • 6.18 有关对象思考:编写电梯模拟程序的类 小结 术语 自测练习 自测练习答案 练习 第7章 与数据抽象(二) 7. 1 简介 7.2 const(常量)对象与const成员函数 7.3 复合:把对象作为成员 7.4 友元函数与友元 ...
  • 14.2.4 定义表达式的抽象接口 490 14.3 定义具体表达式类型 494 14.3.1 联合类型 494 14.3.2 用带标记联合表示表达式 496 14.3.3 可视化具体表示 498 14.3.4 实现构造器和选择器函数 500 14.4 分析表达式 502...
  • 11.19 其他有用的工具 11.20 总结 11.21 练习 第12章 高级应用 12.1 用fork()创建并发进程 12.2 进程的叠加:exec...()函数族系 12.3 使用pipe()实现进程间的通信 12.4 信号 12.5 例子:哲学家用餐问题 12.6 ...
  • 软件工程教程

    2012-07-06 23:10:29
    应用计算机科学、数学及管理科学等原理,以工程化原则和方法来解决软件问题,指导计算机软件开发和维护一门工程学科。  软件工程原则 任务2 软件生命周期与软件开发模型 软件生命周期 软件开发模型 ...
  • 用来做中文OCR的Python3包、中文人物关系知识图谱项目、中文nlp竞赛项目及代码汇总、中文字符数据、speech-aligner: 从“人声语音”及其“语言文本”产生音素级别时间对齐标注的工具、AmpliGraph: 知识图谱表示学习...
  • Tcl_TK编程权威指南pdf

    热门讨论 2011-03-25 09:30:55
    更多有关数学表达式的内容 注释 有关替换与分组的总结 要点 参考 第2章 开始使用 source命令 unix上的tcl脚本程序 .windows 95的开始菜单 macintosh与resedit console命令 命令行变元 预定义变量 第3...
  • 正则表达式入门 - 正则表达式的作用 / 元字符 / 转义 / 量词 / 分组 / 零宽断言 /贪婪匹配与惰性匹配懒惰 / 使用re模块实现正则表达式操作(匹配、搜索、替换、捕获) 使用正则表达式 - re模块 / compile函数 / ...
  • 由阿里电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计一门动态脚本引擎解析工具。 在阿里集团有很强影响力,同时为了自身不断优化、发扬开源贡献精神...
  • 11、集成了一个使用 C 语法的表达式计算器。 12、能够保存多个界面,每个界面内分别包含超过90个独立自定义功能。 13、在文件中可以使用书签来标记重要字节。 14、处理数据时支持超过20个数学操作。 15、文件中...
  • pyarmor:一个用于加密 python 脚本的工具,也可以将加密后的脚本绑定到固件上,或设置已加密脚本的有效期。 shiv:一个命令行工具,可用于构建完全独立的 zip 应用(PEP 441 所描述的那种),同时包含了所有的依赖...
  • 2005-2009软件设计师历年真题

    千次下载 热门讨论 2010-05-18 19:20:10
     • 逻辑代数的基本运算和逻辑表达式的化简  1.4 数学基础知识  • 命题逻辑、谓词逻辑、形式逻辑的基础知识  • 常用数值计算(误差、矩阵和行列式、近似求解方程、插值、数值积分)  • 排列组合、概率论应用...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

java计算数学表达式的工具类

java 订阅