📄 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 + -