您的位置:首页 > 其它

计算一个表达式的值

2007-06-11 23:01 405 查看
中缀表达式 --> 后缀表达式,转换过程中同时计算

操作符堆栈(OperatorHeap):


import java.util.Arrays;




public class OperatorHeap 




...{


    private char[] data;


    private int size;


    


    public OperatorHeap()




    ...{


        this(10);


    }


    public OperatorHeap(int size)




    ...{


        data = new char[size];


        initHeap();


    }


    


    public void initHeap()




    ...{


        data[size++] = '#';


    }


    


    //栈顶


    public char top()




    ...{


        return data[size-1];


    }


    


    //入栈


    public void push(char c)




    ...{


        ensureCapacity(size + 1);


        data[size++] = c;


    }


    


    //出栈


    public char pop()




    ...{


        return data[--size];


    }


    


    //扩展容量


    public void ensureCapacity(int minSize) 




    ...{


        int oldCapacity = data.length;




        if (minSize > oldCapacity) ...{


            int newCapacity = (oldCapacity * 3 / 2 + 1) > minSize ? 


                    oldCapacity * 3 / 2 + 1 : minSize;


            data = (char[]) Arrays.copyOf(data, newCapacity);


        }


    }


}

 

 操作数堆栈(NumHeap):


import java.util.Arrays;




public class NumHeap 




...{


    private double[] data;


    private int size;


    


    public NumHeap()




    ...{


        this(10);


    }


    public NumHeap(int size)




   
15462
 ...{


        data = new double[size];


    }


    


    //栈顶


    public double top()




    ...{


        return data[size-1];


    }


    


    //入栈


    public void push(double c)




    ...{


        ensureCapacity(size + 1);


        data[size++] = c;


    }


    


    //出栈


    public double pop()




    ...{


        return data[--size];


    }


    


    //扩展容量


    public void ensureCapacity(int minSize) 




    ...{


        int oldCapacity = data.length;




        if (minSize > oldCapacity) ...{


            int newCapacity = (oldCapacity * 3 / 2 + 1) > minSize ? 


                    oldCapacity * 3 / 2 + 1 : minSize;


            data = (double[]) Arrays.copyOf(data, newCapacity);


        }


    }


}

 

Eval类,提供了一个静态的eval方法,用于计算表达式值:




/** *//**


 * 计算表达式的值,如 3+(2+9*7)/5


 * @author Liw


 * @time 2007-6


 */




public class Eval 




...{    


    public static double eval(String str)




    ...{


        str = str + "#"; //设置"#"优先级最低,保证opHeap里的运算符能够全部退栈


        String[] words = str.split("(?<!^-?|[+/*()-]-)((?<=[+/*()-])|(?=[+/*()-]))"); //分割表达式


        OperatorHeap opHeap = new OperatorHeap();  //操作符堆栈


        NumHeap numHeap = new NumHeap();  //操作数堆栈


        




        for (int i = 0; i < words.length; i++) ...{




            if (words[i].matches("-?//d+|-?//d+//.//d+")) ...{  //操作数


                numHeap.push(Double.parseDouble(words[i]));  //操作数入栈


            }




            else ...{  //操作符


                char op_top = opHeap.top(), op_cur = words[i].toCharArray()[0]; //栈顶操作符&当前读取的操作符




                while (compare(op_top, op_cur)) ...{  //若当前操作符op_cur优先级低于栈顶,退栈,直到op_cur优先级大于栈顶




                    if ((op_top == '(' && op_cur == ')') || (op_top == '#' && op_cur == '#')) ...{


                        opHeap.pop();  //弹出"(" or "#"


                        break;


                    }




                    else ...{  //弹出一运算符


                        double a = numHeap.pop(), b = numHeap.pop();  //弹出两个数字用于计算


                        numHeap.push(eval2(b, a, opHeap.pop()));  //弹出一运算符,计算两个数的值,结果入栈


                        op_top = opHeap.top();  //新的栈顶


                    }


                }




                if (op_cur != ')') ...{


                    opHeap.push(op_cur);  //操作符op_cur入栈


                }


            }


        }


        


        return numHeap.top();


    }


    


    private static double eval2(double a, double b, char op)




    ...{


        switch (op)




        ...{


        case '+':


            return a + b;


        case '-':


            return a - b;


        case '*':


            return a * b;


        case '/':


            return a / b;


        default:


            return -1;


        }


    }


    


    //返回两个运算符之间的优先级,若op1>op2,返回true


    private static boolean compare(char op1, char op2)




    ...{


        return !(op1 == '(' && op2 == '(')  //连续两括号 <-- false


                && (getOpLevel(op1) == getOpLevel(op2))  //相同运算符 <-- true


                || !(op1 == '(' || op2 == '(' || op1 == '#')  //括号 <-- false


                && getOpLevel(op1) > getOpLevel(op2);  //普通优先级比较


    }


    


    //忽略括号时的优先级


    private static int getOpLevel(char op)




    ...{


        switch(op)




        ...{


        case '+':


        case '-':


            return 1;


        case '*':


        case '/':


            return 2;


        case '(':


        case ')':


            return 0;


        default:


            return -1;  //"#"


        }


    }


}

 

如下使用:


public class Test 




...{


    public static void main(String[] args)




    ...{


        System.out.println(Eval.eval("3+(2+9*7)/5"));


    }


}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  class import string 扩展 c