激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解

Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解

2021-02-28 11:15woider Java教程

這篇文章主要介紹了Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以了解下。

Java字符串轉(zhuǎn)換成算術(shù)表達(dá)式計(jì)算并輸出結(jié)果,通過(guò)這個(gè)工具可以直接對(duì)字符串形式的算術(shù)表達(dá)式進(jìn)行運(yùn)算,并且使用非常簡(jiǎn)單。

這個(gè)工具中包含兩個(gè)類 Calculator 和 ArithHelper

Calculator 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import java.util.Collections;
import java.util.Stack;
/**
 * 算數(shù)表達(dá)式求值
 * 直接調(diào)用Calculator的類方法conversion()
 * 傳入算數(shù)表達(dá)式,將返回一個(gè)浮點(diǎn)值結(jié)果
 * 如果計(jì)算過(guò)程錯(cuò)誤,將返回一個(gè)NaN
 */
public class Calculator {
    private Stack<String> postfixStack = new Stack<String>();
    // 后綴式棧
    private Stack<Character> opStack = new Stack<Character>();
    // 運(yùn)算符棧
    private int[] operatPriority = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };
    // 運(yùn)用運(yùn)算符ASCII碼-40做索引的運(yùn)算符優(yōu)先級(jí)
    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();
            // 運(yùn)算錯(cuò)誤返回NaN
            return 0.0 / 0.0;
        }
        // return new String().valueOf(result);
        return result;
    }
    /**
   * 將表達(dá)式中負(fù)數(shù)的符號(hào)更改
   *
   * @param expression
   *      例如-2+-1*(-3E-2)-(-1) 被轉(zhuǎn)為 ~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);
        }
    }
    /**
   * 按照給定的表達(dá)式計(jì)算
   *
   * @param expression
   *      要計(jì)算的表達(dá)式例如:5+12*(3+5)/7
   * @return
   */
    public double calculate(String expression) {
        Stack<String> resultStack = new Stack<String>();
        prepare(expression);
        Collections.reverse(postfixStack);
        // 將后綴式棧反轉(zhuǎn)
        String firstValue, secondValue, currentValue;
        // 參與計(jì)算的第一個(gè)值,第二個(gè)值和算術(shù)運(yùn)算符
        while (!postfixStack.isEmpty()) {
            currentValue = postfixStack.pop();
            if (!isOperator(currentValue.charAt(0))) {
                // 如果不是運(yùn)算符則存入操作數(shù)棧中
                currentValue = currentValue.replace("~", "-");
                resultStack.push(currentValue);
            } else {
                // 如果是運(yùn)算符則從操作數(shù)棧中取兩個(gè)值和該數(shù)值一起參與運(yùn)算
                secondValue = resultStack.pop();
                firstValue = resultStack.pop();
                // 將負(fù)數(shù)標(biāo)記符改為負(fù)號(hào)
                firstValue = firstValue.replace("~", "-");
                secondValue = secondValue.replace("~", "-");
                String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
                resultStack.push(tempResult);
            }
        }
        return double.valueOf(resultStack.pop());
    }
    /**
   * 數(shù)據(jù)準(zhǔn)備階段將表達(dá)式轉(zhuǎn)換成為后綴式棧
   *
   * @param expression
   */
    private void prepare(String expression) {
        opStack.push(',');
        // 運(yùn)算符放入棧底元素逗號(hào),此符號(hào)優(yōu)先級(jí)最低
        char[] arr = expression.toCharArray();
        int currentIndex = 0;
        // 當(dāng)前字符的位置
        int count = 0;
        // 上次算術(shù)運(yùn)算符到本次算術(shù)運(yùn)算符的字符的長(zhǎng)度便于或者之間的數(shù)值
        char currentOp, peekOp;
        // 當(dāng)前操作符和棧頂操作符
        for (int i = 0; i < arr.length; i++) {
            currentOp = arr[i];
            if (isOperator(currentOp)) {
                // 如果當(dāng)前字符是運(yùn)算符
                if (count > 0) {
                    postfixStack.push(new String(arr, currentIndex, count));
                    // 取兩個(gè)運(yùn)算符之間的數(shù)字
                }
                peekOp = opStack.peek();
                if (currentOp == ')') {
                    // 遇到反括號(hào)則將運(yùn)算符棧中的元素移除到后綴式棧中直到遇到左括號(hào)
                    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]))) {
            // 最后一個(gè)字符不是括號(hào)或者其他運(yùn)算符的則加入后綴式棧中
            postfixStack.push(new String(arr, currentIndex, count));
        }
        while (opStack.peek() != ',') {
            postfixStack.push(String.valueOf(opStack.pop()));
            // 將操作符棧中的剩余的元素添加到后綴式棧中
        }
    }
    /**
   * 判斷是否為算術(shù)符號(hào)
   *
   * @param c
   * @return
   */
    private Boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
    }
    /**
   * 利用ASCII碼-40做下標(biāo)去算術(shù)符號(hào)優(yōu)先級(jí)
   *
   * @param cur
   * @param peek
   * @return
   */
    public Boolean compare(char cur, char peek) {
        // 如果是peek優(yōu)先級(jí)高于cur,返回true,默認(rèn)都是peek優(yōu)先級(jí)要低
        Boolean result = false;
        if (operatPriority[(peek) - 40] >= operatPriority[(cur) - 40]) {
            result = true;
        }
        return result;
    }
    /**
   * 按照給定的算術(shù)運(yùn)算符做計(jì)算
   *
   * @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 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
public class ArithHelper {
    // 默認(rèn)除法運(yùn)算精度
    private static final int DEF_DIV_SCALE = 16;
    // 這個(gè)類不能實(shí)例化
    private ArithHelper() {
    }
    /**
   * 提供精確的加法運(yùn)算。
   *
   * @param v1 被加數(shù)
   * @param v2 加數(shù)
   * @return 兩個(gè)參數(shù)的和
   */
    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();
    }
    /**
   * 提供精確的減法運(yùn)算。
   *
   * @param v1 被減數(shù)
   * @param v2 減數(shù)
   * @return 兩個(gè)參數(shù)的差
   */
    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();
    }
    /**
   * 提供精確的乘法運(yùn)算。
   *
   * @param v1
   *      被乘數(shù)
   * @param v2
   *      乘數(shù)
   * @return 兩個(gè)參數(shù)的積
   */
    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();
    }
    /**
   * 提供(相對(duì))精確的除法運(yùn)算,當(dāng)發(fā)生除不盡的情況時(shí),精確到 小數(shù)點(diǎn)以后10位,以后的數(shù)字四舍五入。
   *
   * @param v1
   *      被除數(shù)
   * @param v2
   *      除數(shù)
   * @return 兩個(gè)參數(shù)的商
   */
    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();
    }
    /**
   * 提供(相對(duì))精確的除法運(yùn)算。當(dāng)發(fā)生除不盡的情況時(shí),由scale參數(shù)指 定精度,以后的數(shù)字四舍五入。
   *
   * @param v1 被除數(shù)
   * @param v2 除數(shù)
   * @param scale 表示表示需要精確到小數(shù)點(diǎn)以后幾位。
   * @return 兩個(gè)參數(shù)的商
   */
    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();
    }
    /**
   * 提供精確的小數(shù)位四舍五入處理。
   *
   * @param v 需要四舍五入的數(shù)字
   * @param scale 小數(shù)點(diǎn)后保留幾位
   * @return 四舍五入后的結(jié)果
   */
    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();
    }
}

使用時(shí)調(diào)用 Calculator 類的 conversion()方法,并傳入算術(shù)表達(dá)式參數(shù),即可返回一個(gè) Double 類型的值。

使用示例:

?
1
2
3
4
5
6
7
8
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();
    }
}

控制臺(tái)輸出:

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

測(cè)試截圖:

Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解

總結(jié)

以上就是本文關(guān)于Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

原文鏈接:https://www.cnblogs.com/woider/p/5331391.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲成年人免费网站 | 成年毛片| 精品一区二区三区免费看 | 久色视频| 外国一级黄色片 | 国产剧情在线观看一区二区 | 一边吃奶一边插下面 | 人人看人人舔 | 国产电影精品久久 | 精品日韩欧美 | 情侣啪啪网站 | 国产一国产一级毛片视频 | 欧美成人三级视频 | 欧美性生交xxxxx免费观看 | 国产大片免费看 | 色人阁五月天 | 精品三区视频 | 欧美大胆xxxx肉体摄影 | 国产免费片 | 91久久久久久久久久久久久久 | 毛片在线免费观看视频 | 精品亚洲夜色av98在线观看 | 毛片免费看的 | 在线观看一二三 | 成人视屏网站 | 九九精品在线观看视频 | 久久久久免费精品国产小说色大师 | 亚洲成人在线免费 | 久久色网站| 韩国精品一区二区三区四区五区 | 国产精品久久999 | 亚洲欧美在线视频免费 | 日本不卡一区二区在线观看 | 九九视频精品在线观看 | 成年免费网站 | 午夜精品久久久久久久久久久久久蜜桃 | 91美女啪啪 | 久久精品日产高清版的功能介绍 | 国产超碰人人做人人爱ⅴa 色天天综合网 | 国产精品区一区二区三区 | 午夜影视一区二区 |