1

我正在尝试解决这个算术表达式问题,我在数组中取 n(这里是 5)个元素并尝试 (+ - *) 中的所有运算符组合,以查找表达式是否可被 101 整除这里,我们不关心顺序操作员..不使用 BODMAS 输入

5

55 3 45 33 25

输出

55+3-45*33-25

我是递归和回溯的新手。我试图了解问题的哪一部分是错误的

这是我的代码:

  public static boolean solve(char []operators,long[]nums,long res,int index,Stack<Character>st){


    if(index+1==nums.length){ //reached end of number array
        if(res%101==0){
            System.out.println(res);
            return true;
        }
        return false;
    }

    for(int i=0;i<operators.length;i++){
        char op=operators[i]; //try the operator
        long num1=nums[index];
        long num2=nums[index+1]; //LINE1

        System.out.println("trying "+num1+""+op+" num2="+num2);
        res=performOp(op,num1,num2);
        nums[index+1]=res; 

        st.push(op);
        if(solve(operators,nums,res,index+1,st)){
            return true;
        }
        //backtrack
        //return to earlier state than try another operator

        //LINE2
        nums[index+1]=performBackTrack(op,num1,num2); //restoring number
        System.out.println("num2="+num2+" num1="+num1+" after backtrack");
        st.pop();

    }

    return false;
} 

  public static long performBackTrack(char op,long num1,long num2){
    //trying to restore numbers
    switch(op){
        case '+':return num2-num1;
        case '-':return num1-num2;
        case '*':return num1/num2;
        default:return 0L;
    }
}

 public static long performOp(char op,long num1,long num2){
    switch(op){
        case '+':return num1+num2;
        case '-':return num1-num2;
        case '*':return num1*num2;
        default:return 0L;
    }
}

在回溯之后,当我在 LINE2 进行更改并进入循环内部尝试下一个运算符时,更改工作正常,因为我在 LINE2 取回了原始号码,但它没有反映在 LINE1,这是我在尝试之前尝试恢复的最后一个号码LINE1 不反映运算符。

请帮助..任何帮助将不胜感激...

4

1 回答 1

0

您的回溯方法存在错误。

您执行res=performOp(op,num1,num2)并分配 的结果nums[index+1]

让我们考虑所有可能的操作以及如何反转它们:

res = num1 + num2      ->  num2 = res - num1
res = num1 - num2      ->  num2 = num1 - res
res = num1 * num2      ->  num2 = res / num1

因此,您应该将resand传递num1performBackTrack,而不是num1and num2

除此之外,performBackTrack应该是这样的:

public static long performBackTrack(char op,long res,long num1) {
//trying to restore numbers
    switch(op){
        case '+':return res - num1;
        case '-':return num1 - res;
        case '*':return res / num1;
        default:return 0L;
    }
}

并且调用performBackTrack应该是:

nums[index+1]=performBackTrack(op,res,num1);

这会产生(对于您给定的输入)以下输出:

trying 55+ num2=3
trying 58+ num2=45
trying 103+ num2=33
trying 136+ num2=25
num2=25 num1=136 after backtrack
trying 136- num2=25
num2=25 num1=136 after backtrack
trying 136* num2=25
num2=25 num1=136 after backtrack
num2=33 num1=103 after backtrack
trying 103- num2=33
trying 70+ num2=25
num2=25 num1=70 after backtrack
trying 70- num2=25
num2=25 num1=70 after backtrack
trying 70* num2=25
num2=25 num1=70 after backtrack
num2=33 num1=103 after backtrack
trying 103* num2=33
trying 3399+ num2=25
num2=25 num1=3399 after backtrack
trying 3399- num2=25
num2=25 num1=3399 after backtrack
trying 3399* num2=25
num2=25 num1=3399 after backtrack
num2=33 num1=103 after backtrack
num2=45 num1=58 after backtrack
trying 58- num2=45
trying 13+ num2=33
trying 46+ num2=25
num2=25 num1=46 after backtrack
trying 46- num2=25
num2=25 num1=46 after backtrack
trying 46* num2=25
num2=25 num1=46 after backtrack
num2=33 num1=13 after backtrack
trying 13- num2=33
trying -20+ num2=25
num2=25 num1=-20 after backtrack
trying -20- num2=25
num2=25 num1=-20 after backtrack
trying -20* num2=25
num2=25 num1=-20 after backtrack
num2=33 num1=13 after backtrack
trying 13* num2=33
trying 429+ num2=25
num2=25 num1=429 after backtrack
trying 429- num2=25
404

并返回true

编辑:

实际上,这要简单得多。你不需要performBackTrack。只需更换

nums[index+1]=performBackTrack(op,num1,num2); //restoring number

nums[index+1]=num2;

毕竟,您正在尝试分配nums[index+1]它在 assignment 之前的值,nums[index+1]=res;这正是num2.

于 2017-11-19T08:43:01.770 回答