学习Java递归,Ackermann函数

时间:2009-10-27 04:18:16

标签: java recursion

我正在使用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));
     }
    }

3 个答案:

答案 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));