?? mycalculator.java
字號:
package edu.bupt.calculate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Stack;
public class MyCalculator {
// 運算符優先級比較函數
static int compare(char a, char b) {
if (a == '*' || a == '/') {
if (b == '(')
return -1;
return 1;
}
if (a == '+' || a == '-') {
if (b == '+' || b == '-' || b == ')' || b == '#')
return 1; // a>b
return -1; // a<b
}
if (a == '(' || a == '#') {
if (a == '(' && b == ')')
return 0; // a==b
else if (a == '(' && b == '#')
return 2; // can't compare
else if (a == '#' && b == ')')
return 2;
else if (a == '#' && b == '#')
return 0;
else
return -1;
}
if (a == ')') {
if (b == '(')
return 2;
else
return 1;
}
return 0;
}
// 判斷表達式中數字的函數
static boolean isNum(char ch) {
if ((ch >= '0' && ch <= '9') || ch == '.')
return true;
return false;
}
// 判斷表達式中運算符的函數
static boolean isOp(char ch) {
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '('
|| ch == ')' || ch == '#')
return true;
return false;
}
// 計算最簡表達式值的函數
// a和b是操作數,s是運算符
static double simpleCalculate(double a, double b, char o) {
if (o == '+')
return a + b; // a+b返回a+b的值
if (o == '-')
return b - a; // 由于操作數出棧順序是后進先出,所以減法和除法要交換參數的順序
if (o == '*')
return a * b; // a*b返回a*b的值
if (o == '/')
return b / a; // 同減法
return 0;
}
// 計算整個表達式值的函數
private static double calculateExpresstion(String s) {
s += "#";
int i = 0;// 表達式循環條件
char c;// 表達式中的一個字符
Stack<Double> num = new Stack<Double>();// 操作數棧
Stack<Character> op = new Stack<Character>();// 操作符棧
op.push('#');// 表達式開始的標志
c = s.substring(i, i + 1).charAt(0);// 取出表達式中的一位
while (c != '#' || op.peek().toString().charAt(0) != '#')// 沒有取到表達式開始或結束的標志'#',就循環計算表達式的值
{
if (isNum(c))// 取到的字符是數字,那么就要取出整個數字
{
int start = i;
int end = 0;
while (isNum(s.substring(i, i + 1).charAt(0)))
// 只要s[i]是數字,就表示一個數還沒完
end = i++;// 循環條件自加
double m = Double.parseDouble(s.substring(start, end + 1));// 取出從i位開始的數字
num.push(m);// 數字入棧
c = s.substring(i, i + 1).charAt(0);// 下一個字符
} else if (isOp(c)) // 取到的字符是運算符
{
switch (compare(op.peek(), c))// 與棧中的運算符比較優先級
{
case -1:// 棧中運算符優先級小于當前運算符
op.push(c);// 運算符入棧
i++;
c = s.substring(i, i + 1).charAt(0);
break;
case 0:// 棧中運算符優先級等于當前運算符
op.pop();// 運算符出棧
i++;
c = s.substring(i, i + 1).charAt(0);
break;
case 1:// 棧中運算符優先級大于當前運算符
// 兩次取出操作數棧中的數
double a = num.pop();
double b = num.pop();
// 取出運算符棧中的運算符
char ss = op.pop();
// 計算結果保存在數字棧中
num.push(simpleCalculate(a, b, ss));
break;
}
}
}
return num.peek();// 表達式計算完畢,返回數字棧中保存的計算結果
}
/**
* // 計算整個表達式值的函數,并保留小數點后兩位
* @param str
* @return
*/
public static double calculate(String str){
BigDecimal result = new BigDecimal(calculateExpresstion(str));
BigDecimal one = new BigDecimal(1);
return result.divide(one, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static void main(String[] args) {
String formula = "";
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
formula = br.readLine();
System.out.println("result = " + MyCalculator.calculate(formula));
} catch (IOException e1) {
System.out.println("您輸入的數字有誤");
} catch (NumberFormatException e2) {
System.out.println("您輸入的數字有誤");
} catch (Exception e) {
e.printStackTrace();
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -