package test.junit;
/**
*计算表达式值,程序在错误表达式检测方面不保证全面,实际使用时就注意手工检查运算式合法.
*使用方法:
*CalculateExpression calc=new CalculateExpression("expression...");
*String result=calc.calculate();
*返回Null时即表示出错.
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
public class CalculateExpressionY {
private ArrayList<String> expression = new ArrayList<String>();// 存储中序表达式
private ArrayList<String> right = new ArrayList<String>();// 存储右序表达式
// 依据输入信息创建对象,将数值与操作符放入ArrayList中
public boolean isOperator(String operator) {
if (operator.equals("+") || operator.equals("-")
|| operator.equals("*") || operator.equals("/")
|| operator.equals("(") || operator.equals(")"))
return true;
else
return false;
}
public int getPriority(String operator) {
if (operator.equals("+") || operator.equals("-")
|| operator.equals("("))
return 1;
else if (operator.equals("*") || operator.equals("/"))
return 2;
else
return 0;
}
/**
* 单步运算
*/
public String singleOperate(String operator, String op1, String op2) {
try {
double x = Double.parseDouble(op2);
double y = Double.parseDouble(op1);
double z = 0;
if (operator.equals("+"))
z = x + y;
else if (operator.equals("-"))
z = x - y;
else if (operator.equals("*"))
z = x * y;
else if (operator.equals("/"))
z = x / y;
else
return null;
return String.valueOf(z);
} catch (NumberFormatException e) {
System.out.println("input has something wrong!");
return null;
}
}
/**
*
* 构造方法
*/
public CalculateExpressionY(String expressioncal) {
/**
* 如果能够以一个字符代替'-'代替减号,'-'只表示负号,如'#',即处理会相对简单的多.
*/
// StringTokenizer st = new StringTokenizer(input, "+-*/()", true);
// while (st.hasMoreElements()) {
// expression.add(st.nextToken());
// }
StringBuffer currentCell = new StringBuffer();
boolean isNeg = true;// true代表是负号,false减号
char[] cs = expressioncal.toCharArray();
int idx = 0;
char temp = 0;
while (idx < cs.length) {
if (cs[idx] == '-') {
if (!isNeg) {
if (temp != ')') {
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
}
currentCell.append(cs[idx]);
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
isNeg = true;
} else {
currentCell.append(cs[idx]);
isNeg = false;
}
} else if (cs[idx] >= '0' && cs[idx] <= '9' || cs[idx] == '.') {
currentCell.append(cs[idx]);
isNeg = false;
} else if (cs[idx] == '+' || cs[idx] == '*' || cs[idx] == '/') {
if (temp != ')') {
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
}
currentCell.append(cs[idx]);
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
isNeg = true;
} else if (cs[idx] == '(') {
if (currentCell.length() == 0) {
currentCell.append(cs[idx]);
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
} else {
expression = null;
return;
}
isNeg = true;
} else if (cs[idx] == ')') {
if (temp != ')') {
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
}
currentCell.append(cs[idx]);
expression.add(currentCell.toString());
currentCell.delete(0, currentCell.length());
isNeg = false;
}
temp = cs[idx++];
}
if (currentCell.toString().trim().length() > 0)
expression.add(currentCell.toString());
} // 将中序表达式转换为右序表达式
private void middletoRight() {
Stack<String> aStack = new Stack<String>();
String operator;
for (String var : expression) {
if (isOperator(var)) {
if (aStack.isEmpty() || var.equals("(")) {
aStack.push(var);
} else {
if (var.equals(")")) {
while (!aStack.isEmpty()
&& !(aStack.peek()).equals("(")) {
operator = aStack.pop();
right.add(operator);
}
if (!aStack.isEmpty() && (aStack.peek()).equals("("))
aStack.pop();// forsake '('
} else {
if (getPriority(var) <= getPriority(aStack.peek())
&& !aStack.isEmpty()) {
operator = aStack.pop();
if (!operator.equals("("))
right.add(operator);
else
aStack.push(operator);
}
aStack.push(var);
}
}
} else
right.add(var);
}
while (!aStack.isEmpty()) {
operator = aStack.pop();
right.add(operator);
}
}
// 对右序表达式进行求值,返回字符串
private String calculate() {
if (expression == null)
return null;
middletoRight();
String result;// 结果
Stack<String> aStack = new Stack<String>();
String op1, op2, is = null;
Iterator<String> it = right.iterator();
while (it.hasNext()) {
is = it.next();
if (isOperator(is)) {
op1 = aStack.pop();
op2 = aStack.pop();
result = singleOperate(is, op1, op2);
if (result != null)
aStack.push(result);
else
return null;
} else
aStack.push(is);
}
result = aStack.pop();
return result;
}
// 测试主函数
public static void main(String args[]) {
String input = "-(2*(10+20)+(-8))*2";
CalculateExpressionY calc = new CalculateExpressionY(input);
System.out.println("result=" + calc.calculate());
}
}