我写了一个代码来打印所有有效的n对括号组合。但是,在我第一次尝试时,算法输出所有组合两次,即。代码是:
public static void solve(char[] string, int open, int closed, int index)
{
if (open < 0 || closed < open) {
return;
}
if (open == 0 && closed == 0) {
System.out.println(string);
}
if (open > 0) {
string[index] = '(';
solve(string, --open, closed, ++index);
}
if (closed > open) {
string[index] = ')';
solve(string, open, --closed, ++index);
}
}
我花了很多时间才能看出出了什么问题。我认为代码进入最后一个if分支比它应该更多。然后,在尝试不同的事情时,我意识到了 改变
solve(string, --open, closed, ++index);
到
solve(string, open-1, closed, ++index);
改变了结果。这导致得到java.lang.ArrayIndexOutOfBoundsException
。最后,我将所有预增量操作替换为相应的算术运算(例如,++index
到index+1
)并且代码正确运行。
我的问题是,不应该--open
和open-1
计算并将相同的值作为参数发送给函数吗?为什么代码在计算相同值时表现不同?
答案 0 :(得分:7)
solve(string, --open, closed, ++index);
实际上将open
更改为比之前更少的一个,这使得下面open
的下一次使用对值的影响小于传入的值。
solve(string, open-1, closed, ++index);
另一方面, ...将open-1
传递给solve方法,但不更改open
,因此在以后使用时它会保持不变语句。
答案 1 :(得分:0)
实际上--x
是一个预递减操作,它始终与x=x-1;
即首先将x递减1,然后将x的递减值分配给x。
因此,当我们执行--x
时,x值肯定会发生变化。
但x-1
只是我们在x上进行的操作,操作是减法。
这里我们将此结果分配给接收此调用的方法中的某个参数。但它没有自动重新分配给x。
所以x-1
永远不会等于x=x-1;
,因此x保持不变,只有接收器才会减去值。
因此
solve(string, --open, closed, ++index);
在上面的陈述中,预先减少在open
上执行。
所以它与open=open-1;
相同,因此开放值发生了变化。
但
solve(string, open-1, closed, ++index);
上面的语句从open
中减去1,并将subratced值传递给method。
与receiveing_variable_in_method_definition = open-1
相同,但开放不会改变。