Java-Fibonacci序列快速算法

Java-Fibonacci序列快速算法,java,fibonacci,Java,Fibonacci,我需要一个关于在Java中为我的独立项目查找斐波那契序列的任务。以下是查找的方法 private static long getFibonacci(int n) { switch (n) { case 0: return 0; case 1: return 1; default: return (getFibonacci(n-1)+getFibonacci(n-2));

我需要一个关于在Java中为我的独立项目查找斐波那契序列的任务。以下是查找的方法

private static long getFibonacci(int n) {
    switch (n) {
        case 0:
            return 0;
        case 1:
            return 1;
        default:
            return (getFibonacci(n-1)+getFibonacci(n-2));
    }
}

private static long getFibonacciSum(int n) {
    long result = 0;

    while(n >= 0) {
        result += getFibonacci(n);
        n--;
    }
    return result;
}

private static boolean isInFibonacci(long n) {
    long a = 0, b = 1, c = 0;

    while (c < n) {
        c = a + b;
        a = b;
        b = c;
    }

    return c == n;
}

代码已完全完成并正在运行。但是,如果n或n2将超过正常值(纤维序列中的第50个数字)?代码将被删除。有什么建议吗?

50或略低于50是直接递归实现的最佳选择。如果您想更进一步,可以切换到迭代或动态规划(DP)方法。我建议从以下内容中学习:。别忘了在大卫的评论中寻找解决方案,真正有效。这些链接显示了如何使用DP方法即时计算偶数
n=500000
。该链接还解释了“记忆”的概念,通过存储中间(但稍后可重新调用)结果来加速计算。

这种解决方法称为动态规划

  • 在这种方法中,我们记住了以前的结果
  • 因此,当递归发生时,cpu不必做任何工作来一次又一次地重新计算相同的值

    class fibonacci
    {
    static int fib(int n)
     {
    /* Declare an array to store Fibonacci numbers. */
       int f[] = new int[n+1];
       int i;
    
       /* 0th and 1st number of the series are 0 and 1*/
       f[0] = 0;
       f[1] = 1;
    
       for (i = 2; i <= n; i++)
       {
           /* Add the previous 2 numbers in the series
            and store it */
           f[i] = f[i-1] + f[i-2];
        }
    
        return f[n];
      }
    
    public static void main (String args[])
        {
           int n = 9;
           System.out.println(fib(n));
        }
    }
    
    类斐波那契
    {
    静态整数fib(整数n)
    {
    /*声明一个数组来存储斐波那契数*/
    int f[]=新的int[n+1];
    int i;
    /*系列的第0和第1个编号分别为0和1*/
    f[0]=0;
    f[1]=1;
    
    对于(i=2;i是的,您可以做的一个改进是
    getFibonacciSum()
    :您可以做与
    isInFibonacci
    完全相同的事情,而不是一次又一次地调用
    isInFibonacci
    ,重新计算所有内容,例如:

    private static boolean getFibonacciSum(long n) {
        long a = 0, b = 1, c = 0, sum = 0;
    
        while (c < n) {
            c = a + b;
            a = b;
            sum += b;
            b = c;            
        }   
        sum += c;    
        return sum;
    }
    
    private静态布尔getFibonacciSum(长n){
    长a=0,b=1,c=0,和=0;
    while(c
    有一种方法可以使用比奈公式来即时计算斐波那契数

    算法:

    一旦你这样做了,你需要知道你正在使用的编程语言以及它的行为。这可能会返回浮点十进制类型,而整数可能是需要的

    该解的复杂性为O(1)

    公共静态长getFib(最终int索引){
    长期a=0,b=0,总计=0;
    
    对于(inti=0;i好,这里是我的解决方案,使用一个映射和{{F(2k)=F(k)[2F(k+1)−F(k)]},{F(2k+1)=F(k+1)^2+F(k)^2}。(公式来源:)

    也可以使用列表而不是地图来实现它,但这只是重新发明轮子

    当使用迭代解决方案时,我们不担心内存不足,但获得fib(1000000)需要很多时间。例如,在这个解决方案中,对于非常大的输入(如10000亿,idk),我们可能会耗尽内存,但速度要快得多

    public BigInteger fib(BigInteger n) {
        if (n.equals(BigInteger.ZERO))
            return BigInteger.ZERO;
        if (n.equals(BigInteger.ONE) || n.equals(BigInteger.valueOf(2)))
            return BigInteger.ONE;
        
        BigInteger index = n;
        
        //we could have 2 Lists instead of a map
        Map<BigInteger,BigInteger> termsToCalculate = new TreeMap<BigInteger,BigInteger>();
        
        //add every index needed to calculate  index n
        populateMapWhitTerms(termsToCalculate, index);
        
        termsToCalculate.put(n,null); //finally add n to map
        
        Iterator<Map.Entry<BigInteger, BigInteger>> it = termsToCalculate.entrySet().iterator();//it 
        it.next(); //it = key number 1, contains fib(1);
        it.next(); //it = key number 2, contains fib(2);
        
        //map is ordered
        while (it.hasNext()) {
            Map.Entry<BigInteger, BigInteger> pair = (Entry<BigInteger, BigInteger>)it.next();//first it = key number 3
            index = (BigInteger) pair.getKey();
            
            if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
                //index is divisible by 2
                //F(2k) = F(k)[2F(k+1)−F(k)]
                pair.setValue(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
                        (((BigInteger.valueOf(2)).multiply(
                                termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).subtract(
                                        termsToCalculate.get(index.divide(BigInteger.valueOf(2)))))));
            }
            else {
                //index is odd
                //F(2k+1) = F(k+1)^2+F(k)^2
                pair.setValue((termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)).multiply(
                        termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).add(
                                (termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
                                termsToCalculate.get(index.divide(BigInteger.valueOf(2))))))
                        );
            }
        }
        
        // fib(n) was calculated in the while loop
        return termsToCalculate.get(n);
    }
    
    private void populateMapWhitTerms(Map<BigInteger, BigInteger> termsToCalculate, BigInteger index) {
        if (index.equals(BigInteger.ONE)) { //stop
            termsToCalculate.put(BigInteger.ONE, BigInteger.ONE);
            return;
            
        } else if(index.equals(BigInteger.valueOf(2))){
            termsToCalculate.put(BigInteger.valueOf(2), BigInteger.ONE);
            return;
            
        } else if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
            // index is divisible by 2
            // FORMUMA: F(2k) = F(k)[2F(k+1)−F(k)]
                        
            // add F(k) key to termsToCalculate (the key is replaced if it is already there, we are working with a map here)
            termsToCalculate.put(index.divide(BigInteger.valueOf(2)), null);
            populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)));
    
            // add F(k+1) to termsToCalculate
            termsToCalculate.put(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE), null);
            populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE));
            
        } else {
            // index is odd
            // FORMULA: F(2k+1) = F(k+1)^2+F(k)^2
    
            // add F(k+1) to termsToCalculate
            termsToCalculate.put(((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)),null);
            populateMapWhitTerms(termsToCalculate,((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)));
    
            // add F(k) to termsToCalculate
            termsToCalculate.put((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)), null);
            populateMapWhitTerms(termsToCalculate, (index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)));
        }
        
    }
    
    public biginger fib(biginger n){
    if(n.equals(BigInteger.ZERO))
    返回biginger.ZERO;
    如果(n.equals(biginger.ONE)| n.equals(biginger.valueOf(2)))
    返回BigInteger.1;
    大整数指数=n;
    //我们可以有两个列表,而不是一张地图
    Map termsToCalculate=新树映射();
    //添加计算索引n所需的每个索引
    populateMapWhitTerms(术语计算、索引);
    termsToCalculate.put(n,null);//最后将n添加到映射
    迭代器it=termsToCalculate.entrySet().Iterator();//它
    it.next();//它=键号1,包含fib(1);
    it.next();//它=键号2,包含fib(2);
    //地图已订购
    while(it.hasNext()){
    Map.Entry pair=(Entry)it.next();//first it=key number 3
    index=(BigInteger)pair.getKey();
    if(index.rements(biginger.valueOf(2)).equals(biginger.ZERO)){
    //索引可以被2整除
    //F(2k)=F(k)[2F(k+1)−F(k)]
    set值(termsToCalculate.get(index.divide(biginger.valueOf(2))).multiply(
    ((biginger.valueOf(2)).multiply(
    termsToCalculate.get(index.divide(biginger.valueOf(2)).add(biginger.ONE)).subtract(
    termsToCalculate.get(index.divide(BigInteger.valueOf(2‘‘‘‘‘‘‘‘)’);
    }
    否则{
    //索引是奇数的
    //F(2k+1)=F(k+1)^2+F(k)^2
    setValue((termsToCalculate.get(index.divide(biginger.valueOf(2)).add(biginger.ONE)).multiply(
    termsToCalculate.get(index.divide(biginger.valueOf(2)).add(biginger.ONE)).add(
    (termsToCalculate.get(index.divide(biginger.valueOf(2))).multiply(
    termsToCalculate.get(index.divide(BigInteger.valueOf(2‘‘‘‘)’))
    );
    }
    }
    //在while循环中计算fib(n)
    返回项stocalculate.get(n);
    }
    私有void populateMapWhitTerms(映射项Stocalculate,BigInteger索引){
    if(index.equals(biginger.ONE)){//stop
    termsToCalculate.put(biginger.ONE,biginger.ONE);
    返回;
    }else if(index.equals(biginger.valueOf(2))){
    termsToCalculate.put(biginger.valueOf(2),biginger.ONE);
    返回;
    }else if(index.rements(biginger.valueOf(2)).equals(biginger.ZERO)){
    //索引可以被2整除
    //FORMUMA:F(2k)=F(k)[2F(k+1)−F(k)]
    //将F(k)键添加到termsToCalculate(如果该键已经存在,则会替换该键,我们正在使用映射)
    termsToCalculate.put(index.divide(biginger.valueOf(2)),null);
    populateMapWhitTerms(termsToCalculate、index.divide(BigInteger.valueOf(2));
    //将F(k+1)添加到termsToCalculate
    termsToCalculate.put(index.divide(biginger.valueOf(2)).add(biginger.ONE),null);
    populateMapWhitTerms(termsToCalculate,index.divide(BigInteger.valueOf(2)).add
    
    function fib(n):
       root5 = squareroot(5)
       gr = (1 + root5) / 2
       igr = 1 - gr
       value = (power(gr, n) - power(igr, n)) / root5
    
       // round it to the closest integer since floating 
       // point arithmetic cannot be trusted to give
       // perfect integer answers. 
       return floor(value + 0.5) 
    
    public static long getFib(final int index) {
            long a=0,b=0,total=0;
            for(int i=0;i<= index;i++) {
                    if(i==0) {
                         a=0;
                         total=a+b;
                     }else if(i==1) {
                         b=1;
                         total=a+b;
                     }
    
                else if(i%2==0) {
                    total = a+b;
                    a=total;                
                }else {
                    total = a+b;
                    b=total;
                }
    
            }
            return total;
        }
    
    public BigInteger fib(BigInteger n) {
        if (n.equals(BigInteger.ZERO))
            return BigInteger.ZERO;
        if (n.equals(BigInteger.ONE) || n.equals(BigInteger.valueOf(2)))
            return BigInteger.ONE;
        
        BigInteger index = n;
        
        //we could have 2 Lists instead of a map
        Map<BigInteger,BigInteger> termsToCalculate = new TreeMap<BigInteger,BigInteger>();
        
        //add every index needed to calculate  index n
        populateMapWhitTerms(termsToCalculate, index);
        
        termsToCalculate.put(n,null); //finally add n to map
        
        Iterator<Map.Entry<BigInteger, BigInteger>> it = termsToCalculate.entrySet().iterator();//it 
        it.next(); //it = key number 1, contains fib(1);
        it.next(); //it = key number 2, contains fib(2);
        
        //map is ordered
        while (it.hasNext()) {
            Map.Entry<BigInteger, BigInteger> pair = (Entry<BigInteger, BigInteger>)it.next();//first it = key number 3
            index = (BigInteger) pair.getKey();
            
            if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
                //index is divisible by 2
                //F(2k) = F(k)[2F(k+1)−F(k)]
                pair.setValue(termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
                        (((BigInteger.valueOf(2)).multiply(
                                termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).subtract(
                                        termsToCalculate.get(index.divide(BigInteger.valueOf(2)))))));
            }
            else {
                //index is odd
                //F(2k+1) = F(k+1)^2+F(k)^2
                pair.setValue((termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)).multiply(
                        termsToCalculate.get(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE)))).add(
                                (termsToCalculate.get(index.divide(BigInteger.valueOf(2))).multiply(
                                termsToCalculate.get(index.divide(BigInteger.valueOf(2))))))
                        );
            }
        }
        
        // fib(n) was calculated in the while loop
        return termsToCalculate.get(n);
    }
    
    private void populateMapWhitTerms(Map<BigInteger, BigInteger> termsToCalculate, BigInteger index) {
        if (index.equals(BigInteger.ONE)) { //stop
            termsToCalculate.put(BigInteger.ONE, BigInteger.ONE);
            return;
            
        } else if(index.equals(BigInteger.valueOf(2))){
            termsToCalculate.put(BigInteger.valueOf(2), BigInteger.ONE);
            return;
            
        } else if(index.remainder(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
            // index is divisible by 2
            // FORMUMA: F(2k) = F(k)[2F(k+1)−F(k)]
                        
            // add F(k) key to termsToCalculate (the key is replaced if it is already there, we are working with a map here)
            termsToCalculate.put(index.divide(BigInteger.valueOf(2)), null);
            populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)));
    
            // add F(k+1) to termsToCalculate
            termsToCalculate.put(index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE), null);
            populateMapWhitTerms(termsToCalculate, index.divide(BigInteger.valueOf(2)).add(BigInteger.ONE));
            
        } else {
            // index is odd
            // FORMULA: F(2k+1) = F(k+1)^2+F(k)^2
    
            // add F(k+1) to termsToCalculate
            termsToCalculate.put(((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)),null);
            populateMapWhitTerms(termsToCalculate,((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)).add(BigInteger.ONE)));
    
            // add F(k) to termsToCalculate
            termsToCalculate.put((index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)), null);
            populateMapWhitTerms(termsToCalculate, (index.subtract(BigInteger.ONE)).divide(BigInteger.valueOf(2)));
        }
        
    }