我正在尝试解决这个算术表达式问题 我在数组中取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。
请帮助......我们将不胜感激任何帮助...
答案 0 :(得分: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
因此,您应该将res
和num1
传递给performBackTrack
,而不是num1
和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]
分配给作业nums[index+1]=res;
之前的值num2
,这正是file.setLastModified(creationDate);
。