不好意思问一下啊; 现在有这么一个需求, 就是传过来的是一个数学表达式 (加减乘除四则运算), 比如 (A + B) * C 这样的; A, B, C 所代表的意义是固定的, 值也可以查到; 那么如何解析这个表达式并计算出结果呢? 我在网上搜了一些方法, 怎么说呢... 感觉都跟想象的差得有点儿远啊... 不知道谁可以帮一下忙, 谢谢大家!

解决方案 »

  1.   

    又是做编译器的吧~以前写过 用stack做的 LZ可以试下 首先要判断()是否匹配遍历完表达时候如果合法就从最内层的表达式算起 现在找不到程序了
      

  2.   

    原来JEP非常好,但现在收费了。找到了这个:http://oursland.net/projects/regexp/是一个applet,但有源代码,自己组织一下吧。
      

  3.   

    /**
     * (#)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;
    }
    }
      

  4.   

    我的BLOG有一个,使用Vector实现的
      

  5.   


    // 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());
    }
      

  6.   

    又是做编译器的吧~以前写过 用stack做的 LZ可以试下 首先要判断()是否匹配遍历完表达时候如果合法就从最内层的表达式算起 现在找不到程序了