我正在使用Java中的递归Ackermann函数。我在may recursive line,23收到错误。
return Ack(m - 1, Ack(m, n - 1));
非常感谢,如果有人能指出什么是错的。
-Kyle
/*enter code here
Ackerman's function, A(m, n) is defined:
A(0 , n) = n + 1 for n >= 0
A(m , 0) = A(m – 1 , 1) for m > 0
A(m , n) = A(m – 1 , A(m , n - 1)) for n >= 0
*/
public class AckFun {
public static int Ack(int m, int n) {
if (m == 0) {
return 2 * n;
} else if (m >= 1) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 2;
} else {
return Ack(m - 1, Ack(m, n - 1));
}
}
return n; // Not sure what to return here, Eclipse suggested this.
}
public static void main(String args[]) {
System.out.println(Ack(3, 4));
}
}
答案 0 :(得分:7)
你需要扩大堆叠:
http://thilinamb.wordpress.com/2008/12/22/how-to-increase-the-java-stack-size/
对于较大的堆栈,它在没有stackoverflow的情况下运行,但是给出0。
编辑:你的代码错了,这就是它给出错误的原因。尝试完全按照定义所说的重写代码:
//I assume that you check that n and m are non-negative before you run this
if (m == 0) {
return n + 1;
} else if (n == 0) {
return Ack(m - 1, 1);
} else {
return Ack(m - 1, Ack(m, n - 1));
}
PS。不要责怪我发布家庭作业问题的源代码。我相信学习编程的最好方法是阅读和理解别人的代码。
答案 1 :(得分:3)
您已超出最大递归深度。这是Ackermann功能的特征之一。 :)
如果用较小的数字(如Ack(3,3)
)调用它,那么它不会溢出堆栈。
可以增加Java的递归深度限制,但这不一定是一个好的解决方案。这可能是转换程序以使其不使用Java的内置调用堆栈,但跟踪数据结构(可能是堆栈)中的每个调用的练习。您还可以使用memoization,在其中记录函数调用的结果,这样您就不必一遍又一遍地计算相同的结果。
答案 2 :(得分:0)
在前面回归,你不需要'其他'。
if (m == 0) return n + 1;
if (n == 0) return ack (m - 1, 1);
return ack (m - 1, ack (m, n - 1));