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

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

表达式:(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());
    }




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值