现在的位置: 首页 > 综合 > 正文

关于java 的科学计算算法(前,中,后缀表达式的转换)——计算器制作的心得

2013年10月09日 ⁄ 综合 ⁄ 共 5239字 ⁄ 字号 评论关闭

  对于没有涉及到高级计算方法的同学们来说,觉得计算器的算法简单。其实不是的。科学领域的计算方法即不顺手也不容易使用,下面说下我在计算器制作过程中对算法心得。

表达式:(5+6)*4-9*(5/6)

这个为通常的表达式。我们用的最多的,这个叫做中缀表达式。但是这个算式在计算器中式难以解析的。尤其在算式长度很长的时候

所以我们通常我把他转为后缀表达式,前缀就不说了,咱PASS,不怎么用,还是后缀好哇。

后缀:56+4*956/*-

童鞋们有没发现这2中表达式的区别么,有么发现后缀的好处。

后缀3大特点:1.运算操作数顺序和中缀一样

    2.没有刮号

    3.不存在优先级

我们惊奇的发现这样的表达式是多么的好解析啊,尤其是在计算器中。


所以我们一般要转后缀表达式用来科学计算哦

至于怎么中转后缀呢?

方法有一些,比较常用的就是用栈机制

初始化2个空堆栈,都来不同时候存取。

一个数组或者STRING用来存结果集。

一:中转后

1.先遍历中缀字符

2.如果是操作数把他放入结果集

3.如果是操作符,弹出(POP),直到遇见刮号或优先级低的操作符,压入堆栈中。

4.遇到(,直接压入栈

5.遇到),在遇到(前面弹出所有操作符,在添加到结果集

6,遍历完毕,弹出所有操作符。添加。

二:后缀求值

1.遍历中缀字符

2.如果是操作数把他放入新堆栈

3.如果是操作符,弹出2个操作数执行操作

4,得到的值继续压入堆栈,求值,循环

5,最后剩一下一个值就是结果了。

 

三:

附加代码把。。





public double chunshi(String f) {


        char c;//用于fortogo中字符的识别和比较


        StringBuffer sb = new StringBuffer(f);//转换StringBuffer实现在运算式后面增加标记@的功能


        sb.append('@');


        String fortogo = sb.toString();//在次转换成String用来提取单个字符


        char[] anArray;//用来存取从栈中取出的数据,


        anArray = new char[100];//不初始化字符不能存储。。。


        Stack<Character> mystack = new Stack<Character>();//定义栈用来存运算符的栈


        while (fortogo.charAt(allspc) != '@') {//遍历fortogo直到@,也就是最后的标记


            c = fortogo.charAt(allspc);//把当前的值给C用于判断


            switch (c) {//判断C


                case '('://是不是(


                    mystack.push(new Character(c));//是的话入栈


                    allspc++;//字符标记下移


                    break;//跳出


                case ')'://实现()的优先级


                    while (mystack.peek().charValue() != '(') {//保证()中有数据,弹出()中的运算符


                        anArray[arrspc++] = mystack.pop().charValue();


                    }


                    mystack.pop();


                    allspc++;


                    break;


                case '+'://加减运算的一样。


                case '-':


                    while (!mystack.empty() && mystack.peek().charValue() != '(') {//不为空,而且上个不为(才入栈


                        anArray[arrspc++] = mystack.pop().charValue();//取得符号前的值入数组


                    }



                    mystack.push(new Character(c));//遍历完毕全部弹出


                    allspc++;


                    break;


                case '*'://乘除一样。。


                case '/':


                    while (!mystack.empty() && (mystack.peek().charValue() == '*' ||//用于限定的入栈条件


                            mystack.peek().charValue() == '/')) {


                        anArray[arrspc++] = mystack.pop().charValue();


                    }


                    mystack.push(new Character(c));


                    allspc++;


                    break;


                default:


                    while ((c >= '0' && c <= '9') || c == '.') {//当输入为数字和.是存入数组


                        anArray[arrspc++] = c;


                        allspc++;


                        c = fortogo.charAt(allspc);


                    }


                    anArray[arrspc++] = '#';//在数字后面加上#做标记


                    break;


            }


        }


        while (!(mystack.empty())) {//把运算符合数据做好联系,好取值


            anArray[arrspc++] = mystack.pop().charValue();


        }


        allspc = 0;//初始化数组标记


        int count;//用于double 型的数据提取


        double a;//用于提取运算符对应的数据


        double b;


        double d;//用于计算一步的值


        Stack<Double> mystack1 = new Stack<Double>();//定义double栈用来存新的值


        while (allspc < arrspc) {//遍历数组


            c = anArray[allspc];


            switch (c) {//取值并计算


                case '+':


                    a = mystack1.pop().doubleValue();


                    b = mystack1.pop().doubleValue();


                    BigDecimal b1 = new BigDecimal(Double.toString(a));


                    BigDecimal b2 = new BigDecimal(Double.toString(b));


                    d = b1.add(b2).doubleValue();


                    mystack1.push(new Double(d));//运算完的值在次存入栈中


                    allspc++;


                    break;



                case '-':


                    a = mystack1.pop().doubleValue();


                    b = mystack1.pop().doubleValue();


                    BigDecimal b11 = new BigDecimal(Double.toString(b));//math中用于精度的调整下面一样


                    BigDecimal b22 = new BigDecimal(Double.toString(a));


                    d = b11.subtract(b22).doubleValue();


                    mystack1.push(new Double(d));


                    allspc++;


                    break;



                case '*':


                    a = mystack1.pop().doubleValue();


                    b = mystack1.pop().doubleValue();


                    BigDecimal b111 = new BigDecimal(Double.toString(a));


                    BigDecimal b222 = new BigDecimal(Double.toString(b));


                    d = b111.multiply(b222).doubleValue();


                    mystack1.push(new Double(d));


                    allspc++;


                    break;



                case '/':


                    a = mystack1.pop().doubleValue();


                    b = mystack1.pop().doubleValue();


                    try {


                        if (a == 0) {


                            throw new Exception();


                        }


                        d = b / a;


                        mystack1.push(new Double(d));


                        allspc++;


                    } catch (Exception e) {


                        jTextField1.setText("除数不能为0");


                        textshow = "";


                        allspc = 0;


                        arrspc = 0;


                        kuanum = 0;


                        haonum = 0;


                        Numcount = false;


                        Symbolcount = false;


                        Symbolcount2 = false;


                        Numcount2 = false;


                        Numcount3 = false;


                        diancount = 0;


                        diancount2 = false;


                        textshow2 = "";


                        denone = 0;


                        dentwo = 0;


                        symbolastrict = true;


                        zerocount = 0;


                        denkua = "";


                        dencount = false;


                    }


                    break;


                default:


                    d = 0;//用于取得一个完成的数据


                    count = 0;


                    while ((c >= '0' && c <= '9')) {


                        d = 10 * d + c - '0';


                        allspc++;


                        c = anArray[allspc];


                    }


                    if (c == '.') {//让.能插入数据中


                        allspc++;


                        c = anArray[allspc];


                        while ((c >= '0' && c <= '9')) {


                            count++;


                            d = d + (c - '0') / Math.pow(10, count);


                            allspc++;


                            c = anArray[allspc];


                        }


                    }


                    if (c == '#') {//遇到#就完成一个数据的提取在存入


                        mystack1.push(new Double(d));


                    }


                    allspc++;


                    break;


            }


        }


        return (mystack1.peek().doubleValue());


    }



抱歉!评论已关闭.