这篇文章主要为大家展示了“Java如何计算数学表达式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java如何计算数学表达式”这篇文章吧。
Java字符串转换成算术表达式计算并输出结果,通过这个工具可以直接对字符串形式的算术表达式进行运算,并且使用非常简单。
这个工具中包含两个类 Calculator 和 ArithHelper
Calculator 代码如下:
import java.util.Collections;import java.util.Stack;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();// 运算错误返回NaNreturn 0.0 / 0.0;}// return new String().valueOf(result);return result;}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);}}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());}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()));// 将操作符栈中的剩余的元素添加到后缀式栈中}}private Boolean isOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';}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;}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() {}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();}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();}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();}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();}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();}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 类型的值。
使用示例:
public class MathTest {public static void main(String[] args) {String expression = "(0*1--3)-5/-4-(3*(-2.13))";double result = Calculator.conversion(expression);System.out.println(expression + " = " + result);System.out.println();}}
控制台输出:
(0*1--3)-5/-4-(3*(-2.13)) = 10.64
测试截图:
以上是“Java如何计算数学表达式”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!