表达式求值的递归与非递归java实现

【问题描述】 给定字符串str,str表示一个数学公式,里面含有运算符加减乘除、数字以及左右括号,返回公式的计算结果,如str="-1+2+3-4*(12-10)",返回-4。

一、递归求解

假设makevalue方法是一个递归求值过程,str="1+2*(3+4)-5"递归求值过程描述如下:

1.从字符串下标0位置开始遍历,如果遍历到’(‘则进入下一层递归;如果遍历到’)'或str遍历完,当前递归调用结束,并向上一递归调用过程返回递归调用结果——遍历结束位置和当前子串计算结果

2.如果遍历到运算符,直接从双端队列deque队尾入队

3.如果遍历到数字num,首先deque尾部元素opr出队,然后判断opr的运算符类型:若opr为’+‘或’-’,则num直接从队尾入队;若opr为’*‘或’/’,为保证其运算优先级,队尾元素pre出队,然后进行num=pre·opr·num运算,最后将运算结果num从队尾入队

递归过程说明:

刚开始进行遍历就进入递归调用makevalue(str,0),当遇到字符’(‘时,从makevalue(str,0)进入递归调用makevalue(str,4),当遇到’)'字符时,makevalue(str,4)递归调用结束,并向makevalue(str,0)返回两个递归调用结果:①makevalue(str,0)遍历结束位置8 ②当前字串的计算结果即"3+4"=7

用数组a[]=new int[2]来保存这两个结果,a[0]=8,用来告知上层调用其下一遍历位置应该从哪儿开始,a[1]=7,存储子串计算结果。对于makevalue(str,0),a[0]保存的是整个字符串str计算结果,a[1]保存的是整个字符串str的长度

子串计算结果说明:

因为每次遇到’(‘就进入下层递归调用,括号()中的子串结果是交给下层函数计算的,上层只需要接受下层返回的计算结果,所以对所有递归过程来说,都是不含字符’(‘和’)’,如对makevalue(str,0)来说,计算的实际上是1+2*7-5,因为(3+4)是交给下层makevalue(str,4)计算完成的,自己只需要接受下层返回的结果7

通过2、3步描述和以上说明,不难可以看出双端队列deque实际上保存的就是当前递归过程不包含字符’(‘和’)’,也不包含字符’*‘和’/’(见3)的字符串,只包含操作符‘+’、‘-’和操作数,即对makevalue(str,0)来说,deque={“1”,"+",“14”,"-",“5”},对makevalue(str,4)来说,deque={“3”,"+",“4”}

【算法描述】

    public static int[] makeValue(char[] chas, int i) {
   
        int val = 0;
        int[] a = new int[2];
        Deque<String> deque = new LinkedList<String>();
        while (i < chas.length && chas[i] != ')') {
   
            if (chas[i] >= '0' && chas[i] <= '9')
                val = val * 10 + chas[i++] - '0';
            else if (chas[i] != '(') {
      //chas[i] in {+-*/}
                addNum(deque, val);
                deque.addLast(String.valueOf(chas[i++]));
                val = 0;
            } else {
   
                a = makeValue(chas, i + 1);
                val = a[0];
                i = a[1] + 1;
            }
        }
        addNum(deque, val);
        return new int[]{
   popNum(deque), i};
    }

    public static void addNum(Deque<String> deque, int num) {
   
        if (!deque.
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值