package com . math ; import java . math . BigDecimal ; import java . util . ArrayList ; import java . util . Scanner ; import java . util . Stack ; /** * 表达式求值 */ public class Calculator { private static final int MAXCAPACITY = 50
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
/**
* 表达式求值
*/
public class Calculator {
private static final int MAXCAPACITY = 500;
private String expression;
public Calculator(String expression) {
if (expression.length() > MAXCAPACITY)
System.out.println("字符串长度超出最大值");
else
this.expression = expression;
}
public int getPriority(String str) {
int pri = -1;
if (str.equals("("))
pri = 0;
else if (str.equals("+") || str.equals("-"))
pri = 1;
else if (str.equals("*") || str.equals("/"))
pri = 2;
return pri;
}
public String[] split() {
ArrayList<String> strList = new ArrayList<String>();
int splitIndex = 0;
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) == '+' || expression.charAt(i) == '-' || expression.charAt(i) == '*' || expression.charAt(i) == '/' || expression.charAt(i) == '(' || expression.charAt(i) == ')') {
if (splitIndex == i) { //处理连续多个操作符
if (expression.charAt(i) == '-') { //处理操作符"( + - * /"符号后面遇到"-"情况时,将后面的数字当做负数处理
splitIndex = i;
continue;
} else
strList.add(expression.substring(splitIndex, i + 1));
} else {
strList.add(expression.substring(splitIndex, i));
strList.add(expression.substring(i, i + 1));
}
splitIndex = i + 1;
}
if ((i == expression.length() - 1) && (splitIndex <= i))
strList.add(expression.substring(splitIndex));
}
return strList.toArray(new String[0]);
}
public String[] getSuffixExpression(String[] expression) {
Stack<String> strStack = new Stack<String>();
ArrayList<String> strList = new ArrayList<String>();
for (int i = 0; i < expression.length; i++) {
if (expression[i].equals("(")) //遇到'('时入栈
strStack.push(expression[i]);
else if (expression[i].equals("+") || expression[i].equals("-") || expression[i].equals("*") || expression[i].equals("/")) {
if (strStack.isEmpty()) //栈空时操作符入栈
strStack.push(expression[i]);
else { //否则比较栈顶操作符优先级
while ((!strStack.isEmpty()) && (getPriority(strStack.peek()) >= getPriority(expression[i]))) {
strList.add(strStack.pop());
}
strStack.push(expression[i]);
}
} else if (expression[i].equals(")")) {//遇到')'时出栈直至'('
while (!strStack.peek().equals("(")) {
strList.add(strStack.pop());
}
strStack.pop(); //抛出'('
} else
strList.add(expression[i]);
}
while (!strStack.isEmpty())
strList.add(strStack.pop());
return strList.toArray(new String[0]);
}
public double getResult(String[] expression) {
Stack<Double> strStack = new Stack<Double>();
double num1, num2;
double result = 0;
for (int i = 0; i < expression.length; i++) {
if (expression[i].equals("+") || expression[i].equals("-") || expression[i].equals("*") || expression[i].equals("/")) {
String str = expression[i];
switch (str) {
case "+": {
num1 = strStack.pop();
num2 = strStack.pop();
//BigDcimal的作用:解决计算过程中丢失精度问题
result = (BigDecimal.valueOf(num1).add(BigDecimal.valueOf(num2))).doubleValue();
strStack.push(result);
break;
}
case "-": {
num1 = strStack.pop();
num2 = strStack.pop();
result = (BigDecimal.valueOf(num2).subtract(BigDecimal.valueOf(num1))).doubleValue();
strStack.push(result);
break;
}
case "*": {
num1 = strStack.pop();
num2 = strStack.pop();
result = num2 * num1;
result = (BigDecimal.valueOf(num2).multiply(BigDecimal.valueOf(num1))).doubleValue();
strStack.push(result);
break;
}
case "/": {
num1 = strStack.pop();
num2 = strStack.pop();
result = (BigDecimal.valueOf(num2).divide(BigDecimal.valueOf(num1))).doubleValue();
strStack.push(result);
break;
}
}
} else
strStack.push(Double.valueOf(expression[i]));
}
result = 0;
while (!strStack.isEmpty()) {
result += strStack.pop();
}
return result;
}
public double getResult() {
return getResult(getSuffixExpression(split()));
}
/**
* 计算包含+、-、*、/、(、)等几种运算符的表达式的值。
*/
public static void main(String[] args) {
try { //第一步:输入包含表达式的字符串
Scanner scanner = new Scanner(System.in);
System.out.println("请输入表达式并以#结束:");
//第二步:计算表达式的值
StringBuffer sb = new StringBuffer();
while (true) {
String s = scanner.next();
sb.append(s);
if (sb.toString().endsWith("#")) {
break;
}
if (sb.toString().equals("#")) {
System.out.println("请输入表达式");
}
}
String line = sb.toString().substring(0, sb.toString().length() - 1);
//第三步:输出计算结果
Calculator exp1 = new Calculator(line);
String[] strSplit = exp1.split();
String[] strSuffixExpression = exp1.getSuffixExpression(strSplit);
double result = exp1.getResult(strSuffixExpression);
System.out.println("计算结果:" + line + "=" + result);
} catch (Exception e) {
System.err.println("请输入合法的表达式!");
}
}
}