【问题标题】:How do I implement Tail recursion with my Fibonacci method?如何使用我的斐波那契方法实现尾递归?
【发布时间】:2018-02-17 22:44:17
【问题描述】:

我正在尝试计算大量斐波那契数列,因此我使用大整数。我最多可以达到 10000 个,但是我的堆栈空间用完了。我意识到我可以增加堆栈和堆空间,但我的理解是尾递归可以解决空间问题。这是我的代码..

public class FibRecursion{

static BigInteger[] fval;

public static void main(String[] args) {

    int index;

    Scanner input = new Scanner(System.in);

    index = input.nextInt();


    fval = new BigInteger[index + 1];


    System.out.println(fib_rec(index));


}


public static BigInteger fib_rec(int index){


    BigInteger result = BigInteger.ONE;

    if(index <= 2){
        return result;
    }

    else{
        if(fval[index] != null){
            result=fval[index];
        }
        else{
            result = fib_rec(index-1).add(fib_rec(index-2));

            fval[index] = result;

        }
        return result;
    }
}  
}

【问题讨论】:

  • Java 没有尾递归。但是你可以只使用迭代公式
  • 请参阅stackoverflow.com/questions/32685660/… 可能会有所帮助
  • 尾递归消除,即使 java 有它,在这种情况下也无济于事。让任何递归代码变得高效的不仅仅是一些魔法尘埃。

标签: java recursion fibonacci tail-recursion


【解决方案1】:

实现您想要的系列的简单递归可能是:

public class FibRecursion{

    private static BigInteger[] fval;

    public static void main(String[] args) {

        int index = 10;
        fval = new BigInteger[index];
        fib(0,1,0,index);
        System.out.println(Arrays.toString(fval));
    }

    public static void fib(long a, long b, int index, int endIndex ) {

        if (index >= endIndex) {

            return ;
        }

        fval[index] = BigInteger.valueOf(a).add(BigInteger.valueOf(b));
        index++;
        fib(b, a+b, index , endIndex);
    }
}

为避免堆栈限制,您可以限制递归深度并在几个“片段”中进行复活。这是一系列 50 个元素的示例,计算深度限制为 10 (RECURRSION_DEPTH = 10):

public class FibRecursion{

    private static BigInteger[] fval;
    //limit of the recursion depth. valid values are >=2
    private final static int RECURRSION_DEPTH = 10;

    public static void main(String[] args) {

        int index = 50;
        fval = new BigInteger[index];

        BigInteger aValue = BigInteger.valueOf(0);
        BigInteger bValue = BigInteger.valueOf(1);
        int startIndex = 0;
        int endIndex = RECURRSION_DEPTH;

        while (endIndex > startIndex) {

            fib(aValue,bValue,startIndex,endIndex);

            aValue = fval[endIndex-2];
            bValue = fval[endIndex-1];
            startIndex = endIndex;
            endIndex = Math.min(endIndex + RECURRSION_DEPTH, index);
        }

        System.out.println(Arrays.toString(fval));
    }

    //use BigInteger to avoid integer max value limitation 
    public static void fib(BigInteger a, BigInteger b, int index, int endIndex ) {

        if (index >= endIndex) {

            return ;
        }

        fval[index] = a.add(b);
        index++;
        fib(b, a.add(b), index , endIndex);
    }
}

这当然还有其他限制,与堆栈大小无关。

【讨论】:

    猜你喜欢
    • 2014-04-02
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 2021-11-27
    • 2019-01-21
    • 2019-09-03
    相关资源
    最近更新 更多