栈实现综合计算器(2)

栈实现综合计算器(2)

优点:可以实现多位数的加减乘除的计算
缺点:中缀表达式的求值是我们人最熟悉的,但是对计算机来说却不好操作。

思路分析

  • 当我们把表达式存储在一个字符串当中时候,每次用index去扫描,对于多位数,我们就可以看作是多个单个字符串的拼接。
  • 因此,每次当我们利用index进行扫描读取数据的时候,还需要考虑index的下一位,如果是数据的话,就继续向下一位扫描,直到是操作符为止
  • 然后将数据拼接后,可以利用包装类再将字符串转换成数据的形式,便于接下去的计算操作。

代码实现

其余部分的代码详细可见栈实现综合计算器(1),此处展示的是,在处理数据时候的代码的变化。同时,需要在主函数一开始定义一个String类型的变量,来保存和拼接多位数的数据。

String keepNum = "";//用于拼接多位数
        // 1.首先,扫描表达式expression
        while (true) {
            // 依次得到每一个字符
            ch = expression.substring(index, index + 1).charAt(0);
            // 判断ch是数字还是操作符,然后做相应的操作
            if (operStack.isOper(ch)) {
                // 如果是操作符,两种情况:1.operStack内有操作符,判断优先级2.没有操作符,直接入栈
                // 没有操作符,直接入栈
                if (operStack.isEmpty()) {
                    operStack.pushNum(ch);
                } else {
                    // 如果栈顶有操作符,两种思路:
                    // 1.如果优先级ch > 栈顶的,直接入栈
                    // 2.如果优先级ch < 栈顶的,先把栈顶的取出来,并且从数据栈中取数做运算,然后分别把结果和ch再入栈到对应的栈中
                    if (operStack.priority(ch) <= operStack.priority(operStack.peak())) {
                        // 1.取出数据和操作符
                        num1 = numStack.popNum();
                        num2 = numStack.popNum();
                        oper = operStack.popNum();
                        // 2.做运算
                        res = numStack.cal(num1, num2, oper);
                        // 3.对应的数据和操作符入栈
                        numStack.pushNum(res);
                        operStack.pushNum(ch);

                    } else {
                        operStack.pushNum(ch);
                    }
                }

            } else {
                // 如果是数字。直接入栈——numStack
                // numStack.pushNum(ch - 48);// 此时因为是字符的格式,在Ascii码表中,数字和对应的字符格式相差48
                //处理多位数的思路:
                //需要让index扫描时候往index+1的位置上再多扫描一次,如果是数就继续向下一位扫描,如果index+1位是操作符,才将这个数入栈
                //keepNum用于数字的拼接

                //处理多位数
                keepNum += ch;

                if(index == expression.length()-1){//此时,index已经是最后一位,直接入栈
                    numStack.pushNum(Integer.parseInt(keepNum));//包装类和字符串的转换

                }else{
                    if(operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))){
                        numStack.pushNum(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
            }
            index++;
            if(index >= expression.length()){
                break;
            }
        }

后续

因为考虑到这种方法的不便,所以我们可以通过逆波兰表达式的方式来实现综合计算器的效果。

拓展

  • 前缀表达式:前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前
    - 如:(3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6
    - 计算方法:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
  • 中缀表达式:中缀表达式就是常见的运算表达式,如(3+4)×5-6
    - 中缀表达式的求值是我们人最熟悉的,但是对计算机来说却不好操作(前面我们演示的综合计算器就能看的这个问题),因此,在计算结果时,往往会将中缀表达式转成其它表达式来操作(一般转成后缀表达式.)
  • 后缀表达式:后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后。
    - 如:(3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 –
    - 还有其他的逆波兰表达式,如:
    逆波兰表达式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值