不好意思问一下啊; 现在有这么一个需求, 就是传过来的是一个数学表达式 (加减乘除四则运算), 比如 (A + B) * C 这样的; A, B, C 所代表的意义是固定的, 值也可以查到; 那么如何解析这个表达式并计算出结果呢? 我在网上搜了一些方法, 怎么说呢... 感觉都跟想象的差得有点儿远啊... 不知道谁可以帮一下忙, 谢谢大家!
public double cal(String exp) { exp = adj(exp); exp = conver(exp); Stack<Object> stack = new Stack<Object>(); String[] cs = exp.split("[^\\d.+\\-*/]+"); int i = 0; while (i < cs.length) { String c = cs[i]; i++; if ("+".equals(c)) { stack.push( Double.parseDouble(stack.pop().toString()) + Double.parseDouble(stack.pop().toString()) ); } else if ("-".equals(c)) { stack.push( 0 - Double.parseDouble(stack.pop().toString()) + Double.parseDouble(stack.pop().toString()) ); } else if ("*".equals(c)) { stack.push( Double.parseDouble(stack.pop().toString()) * Double.parseDouble(stack.pop().toString()) ); } else if ("/".equals(c)) { stack.push( 1 / Double.parseDouble(stack.pop().toString()) * Double.parseDouble(stack.pop().toString()) ); } else { stack.push(c); } } return Double.parseDouble(stack.pop().toString()); } private String adj(String exp) { exp = Pattern.compile("[^\\d.+\\-*\\/()]+").matcher(exp).replaceAll(""); exp = Pattern.compile("(^|[(+\\-*\\/])\\-([\\d.]+)").matcher(exp).replaceAll("$1(0-$2)"); exp = Pattern.compile("[+\\-*\\/()]").matcher(exp).replaceAll(" $0 ").trim(); return exp; }
private String conver(String exp) { String[] str = exp.split("\\s+"); Stack<String> expStack = new Stack<String>(); for(int i = str.length - 1 ; i >= 0 ; i--) expStack.push(str[i]); Stack<String> outStack = new Stack<String>(); Stack<String> operStack = new Stack<String>(); operStack.push("#"); while (expStack.size()> 0) { String c = expStack.pop().toString(); if (c.matches("^\\d+(?:\\.\\d*)?$")) { outStack.push(c); } else if ("(".equals(c)) { operStack.push(c); } else if (")".equals(c)) { if (operStack.lastElement().equals("(")) { operStack.pop(); } else { expStack.push(c); outStack.push(operStack.pop()); } } else { if (comparison(c, operStack.lastElement())) outStack.push(operStack.pop()); operStack.push(c); } } operStack.remove(operStack.firstElement()); while(!operStack.empty()) outStack.push(operStack.pop()); return outStack.toString().replaceAll("\\[|\\]|\\,", ""); }
public int getLevel(Object o) { if ("(".equals(o)) return 1; if ("+".equals(o)) return 2; if ("-".equals(o)) return 2; if ("*".equals(o)) return 3; if ("/".equals(o)) return 3; return -1; }
* (#)Calculator.java 创建时间:Apr 30, 2009 6:14:03 PM<br />
*/
package cn.ialvin.util;import java.util.Stack;
import java.util.regex.Pattern;/**
* @author 林志斌(<b>ialvin.cn</b>) 广东 普宁 里湖
*/
public class Calculator {
public static void main(String[] args) {
String exp = "-3.3 + 1 * - 3 + -5";
Calculator calculator = new Calculator();
System.out.println(calculator.cal(exp));
}
public double cal(String exp) {
exp = adj(exp);
exp = conver(exp);
Stack<Object> stack = new Stack<Object>();
String[] cs = exp.split("[^\\d.+\\-*/]+");
int i = 0;
while (i < cs.length) {
String c = cs[i]; i++;
if ("+".equals(c)) {
stack.push(
Double.parseDouble(stack.pop().toString()) +
Double.parseDouble(stack.pop().toString())
);
} else if ("-".equals(c)) {
stack.push(
0 - Double.parseDouble(stack.pop().toString()) +
Double.parseDouble(stack.pop().toString())
);
} else if ("*".equals(c)) {
stack.push(
Double.parseDouble(stack.pop().toString()) *
Double.parseDouble(stack.pop().toString())
);
} else if ("/".equals(c)) {
stack.push(
1 / Double.parseDouble(stack.pop().toString()) *
Double.parseDouble(stack.pop().toString())
);
} else {
stack.push(c);
}
}
return Double.parseDouble(stack.pop().toString());
} private String adj(String exp) {
exp = Pattern.compile("[^\\d.+\\-*\\/()]+").matcher(exp).replaceAll("");
exp = Pattern.compile("(^|[(+\\-*\\/])\\-([\\d.]+)").matcher(exp).replaceAll("$1(0-$2)");
exp = Pattern.compile("[+\\-*\\/()]").matcher(exp).replaceAll(" $0 ").trim();
return exp;
}
private String conver(String exp) {
String[] str = exp.split("\\s+");
Stack<String> expStack = new Stack<String>();
for(int i = str.length - 1 ; i >= 0 ; i--)
expStack.push(str[i]);
Stack<String> outStack = new Stack<String>();
Stack<String> operStack = new Stack<String>();
operStack.push("#");
while (expStack.size()> 0) {
String c = expStack.pop().toString();
if (c.matches("^\\d+(?:\\.\\d*)?$")) {
outStack.push(c);
} else if ("(".equals(c)) {
operStack.push(c);
} else if (")".equals(c)) {
if (operStack.lastElement().equals("(")) {
operStack.pop();
} else {
expStack.push(c);
outStack.push(operStack.pop());
}
} else {
if (comparison(c, operStack.lastElement()))
outStack.push(operStack.pop());
operStack.push(c);
}
}
operStack.remove(operStack.firstElement());
while(!operStack.empty())
outStack.push(operStack.pop());
return outStack.toString().replaceAll("\\[|\\]|\\,", "");
}
public int getLevel(Object o) {
if ("(".equals(o)) return 1;
if ("+".equals(o)) return 2;
if ("-".equals(o)) return 2;
if ("*".equals(o)) return 3;
if ("/".equals(o)) return 3;
return -1;
}
public boolean comparison(String c1 ,Object c2) {
return getLevel(c2)-getLevel(c1) >= 0;
}
}
// cal 方法 修改一下
public double cal(String exp) {
exp = adj(exp);
exp = conver(exp);
Stack<Object> stack = new Stack<Object>();
String[] cs = exp.split("[^\\d.+\\-*/]+");
int i = 0;
while (i < cs.length) {
String c = cs[i]; i++;
if ("+".equals(c)) {
stack.push((Double)stack.pop() + (Double)stack.pop());
} else if ("-".equals(c)) {
stack.push(0 - (Double)stack.pop() + (Double)stack.pop());
} else if ("*".equals(c)) {
stack.push((Double)stack.pop() * (Double)stack.pop());
} else if ("/".equals(c)) {
stack.push(1 / (Double)stack.pop() * (Double)stack.pop());
} else {
stack.push(Double.parseDouble(c));
}
}
return Double.parseDouble(stack.pop().toString());
}