我如何打破这个递归调用?
How do I break out of this recursive call?
我是递归新手,还在学习中,逻辑不好请大家多多包涵。我有这个函数,它有 5 个参数 a、b、c、x、y。所以我基本上想做的是从这些变量中的任何一个中取出一个元素并将其添加到另一个以最终得到 x , y 。我想自己尝试一下,我几乎完成了,只是我想问一下,一旦我得到“是”的答案,是否有任何方法可以摆脱这个递归调用。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String in = sc.nextLine();
int[] input = new int[10];
for(int i=0; i < 10; i=i+2) {
input[i] = Integer.parseInt(String.valueOf(in.charAt(i)));
}
int A = input[0];
int B = input[2];
int C = input[4];
int X = input[6];
int Y = input[8];
persistent(A,B,C,X,Y);
}
private static void persistent(int a, int b, int c, int x, int y) {
if(a == 0 || b == 0 || c == 0) {
if((a == x && b == y) && (b == x && a == y)) {
System.out.println("YES");
}
else if((b == x && c == y) || (c == x && b == y)) {
System.out.println("YES");
}
else if((a == x && c == y) && (c == x && a == y)) {
System.out.println("YES");
}
else {
return;
}
}
persistent(a-1,b+1,c,x,y);
persistent(a-1,b,c+1,x,y);
persistent(a+1,b-1,c,x,y);
persistent(a,b-1,c+1,x,y);
persistent(a+1,b,c-1,x,y);
persistent(a,b+1,c-1,x,y);
}
你的代码永远不会。
几乎所有递归算法归结为完全相同的风格:
首先,检查是否达到了某些边缘情况(通常是最简单的情况)。在这种情况下,立即 return - 不要递归。通过同义反复,如果答案很简单,你可以直接给出它而无需递归,这定义了 'edge case' / 'simple case'。 必须至少有一个这样的情况,否则递归算法将无法工作。
否则,请提供您的答案并随意使用任意数量的递归调用,但这些调用的最后一个 必须是更简单,其定义是严格更接近 1.
中提到的简单情况
所有状态都是通过参数传递的。通常有一个私有的辅助方法来完成实际的工作,它有一堆额外的参数,而 public API 是一个调用辅助的单行代码,为那些提供初始值额外的参数。只有没有这种状态才能省略这个。
您的代码没有这样做。有一个简单的情况,如果a或b或c为0,但是你的6次递归调用并没有明显地走向简单。
修复不明显。你的算法不能像写的那样工作,如果不重新考虑它就不能修复。
希望以上内容对您有所帮助:您的递归调用需要以某种方式变得更简单,保证。现在不能保证:是的,每次调用都会将 3 个数字中的一个移近边缘情况(为 0),但没有明确的流程:如果我用 3/4/5
作为参数调用你的代码,然后它使用 2/5/5
、2/4/6
等进行递归调用。第一个调用 (2/5/5
) not 保证更接近边缘情况,因为作为其调用堆栈的一部分,它将再次执行 3/4/5
。
我是递归新手,还在学习中,逻辑不好请大家多多包涵。我有这个函数,它有 5 个参数 a、b、c、x、y。所以我基本上想做的是从这些变量中的任何一个中取出一个元素并将其添加到另一个以最终得到 x , y 。我想自己尝试一下,我几乎完成了,只是我想问一下,一旦我得到“是”的答案,是否有任何方法可以摆脱这个递归调用。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String in = sc.nextLine();
int[] input = new int[10];
for(int i=0; i < 10; i=i+2) {
input[i] = Integer.parseInt(String.valueOf(in.charAt(i)));
}
int A = input[0];
int B = input[2];
int C = input[4];
int X = input[6];
int Y = input[8];
persistent(A,B,C,X,Y);
}
private static void persistent(int a, int b, int c, int x, int y) {
if(a == 0 || b == 0 || c == 0) {
if((a == x && b == y) && (b == x && a == y)) {
System.out.println("YES");
}
else if((b == x && c == y) || (c == x && b == y)) {
System.out.println("YES");
}
else if((a == x && c == y) && (c == x && a == y)) {
System.out.println("YES");
}
else {
return;
}
}
persistent(a-1,b+1,c,x,y);
persistent(a-1,b,c+1,x,y);
persistent(a+1,b-1,c,x,y);
persistent(a,b-1,c+1,x,y);
persistent(a+1,b,c-1,x,y);
persistent(a,b+1,c-1,x,y);
}
你的代码永远不会。
几乎所有递归算法归结为完全相同的风格:
首先,检查是否达到了某些边缘情况(通常是最简单的情况)。在这种情况下,立即 return - 不要递归。通过同义反复,如果答案很简单,你可以直接给出它而无需递归,这定义了 'edge case' / 'simple case'。 必须至少有一个这样的情况,否则递归算法将无法工作。
否则,请提供您的答案并随意使用任意数量的递归调用,但这些调用的最后一个 必须是更简单,其定义是严格更接近 1.
中提到的简单情况所有状态都是通过参数传递的。通常有一个私有的辅助方法来完成实际的工作,它有一堆额外的参数,而 public API 是一个调用辅助的单行代码,为那些提供初始值额外的参数。只有没有这种状态才能省略这个。
您的代码没有这样做。有一个简单的情况,如果a或b或c为0,但是你的6次递归调用并没有明显地走向简单。
修复不明显。你的算法不能像写的那样工作,如果不重新考虑它就不能修复。
希望以上内容对您有所帮助:您的递归调用需要以某种方式变得更简单,保证。现在不能保证:是的,每次调用都会将 3 个数字中的一个移近边缘情况(为 0),但没有明确的流程:如果我用 3/4/5
作为参数调用你的代码,然后它使用 2/5/5
、2/4/6
等进行递归调用。第一个调用 (2/5/5
) not 保证更接近边缘情况,因为作为其调用堆栈的一部分,它将再次执行 3/4/5
。