1

I am trying to solve this arithmetic expression problem where I take n (here 5) elements in an array and try all combination of operators in (+ - *) to find if the expression is divisible by 101 Here, we are not concerned with order of operators..not using BODMAS Input

5

55 3 45 33 25

Output

55+3-45*33-25

I am new at recursion and backtracking. I am trying to understand which part of the problem is wrong

Here's my code:

  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;
    }
}

Here after backtracking, when I make changes at LINE2 and go inside the loop to try next operator, the change works fine as I get back the orignal number at LINE2 but it is not reflected at LINE1, the last number I try to restore before trying an operator is not reflected at LINE1.

Please help..Any kind of help will be appreciated ...

Learner
  • 61
  • 1
  • 7

1 Answers1

0

You have a bug in your back-tracking method.

You perform res=performOp(op,num1,num2) and assign the result of nums[index+1].

Let's consider all the possible operations and how to reverse them:

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

Therefore, you should pass res and num1 to performBackTrack, not num1 and num2.

Besides that, performBackTrack should look like this:

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;
    }
}

and the call to performBackTrack should be:

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

This produces (for your given input) the following output:

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

and returns true.

EDIT:

Actually, this is much simpler. You don't need performBackTrack. Just replace

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

with

nums[index+1]=num2;

After all, you are trying to assign to nums[index+1] the value that it had before the assignment nums[index+1]=res;, which is precisely num2.

Eran
  • 387,369
  • 54
  • 702
  • 768