I am working with fibonacci numbers, where the "n" for the n-th number is in 5-6 digits. how can i reduce the time taken for execution?

huangapple go评论83阅读模式
英文:

I am working with fibonacci numbers, where the "n" for the n-th number is in 5-6 digits. how can i reduce the time taken for execution?

问题

在这个特定的问题中,我需要找到斐波那契数列中的数字,对它们进行平方,然后找到这些平方数的总和。这一切都进行得很顺利,直到长整型数据类型的范围限制。

到目前为止,我已经做了以下工作... 在注意到长整型的范围无法处理大的斐波那契数之后,我切换到了 BigInteger,这解决了问题,但指数级增加了时间复杂度。由于我需要保留大部分数字,所以我需要创建一个数组来存储它们。

import java.util.*;
import java.math.*;
public class FibonacciSumSquares {
    private static BigInteger getFibonacciSumSquares(int n) {

        if (n <= 1)
            return BigInteger.valueOf(n);

        BigInteger sum = BigInteger.valueOf(0);
        BigInteger a[] = new BigInteger[n];
        a[0] = a[1] = BigInteger.ONE;
        for (int i = 2; i < n; i++) {
            a[i] = a[i - 1].add(a[i - 2]);
            a[i] = a[i].pow(2);
            sum = sum.add(a[i]);
        }
        return sum;

    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();

        System.out.println(getFibonacciSumSquares(n));
    }
}

接受第一个答案后,我对代码片段进行了一些压力测试,需要的修正是代码中需要一个 "=" 符号。希望这有所帮助。有关更多详细信息,请参考答案的评论。

英文:

In this specific problem, what I had to do is find the Fibonacci numbers, square them, and then find the sum of those squared numbers. Which was fine up until the range limit of the long data type.

Here's what I've got till now... I switched to BigInteger after noticing that the range of long couldn't handle the large Fibonacci numbers, and that did the trick but increased the time complexity exponentially. And since I needed to retain most of the numbers, I needed to make an array for the numbers to store them.

import java.util.*;
import java.math.*;
public class FibonacciSumSquares {
    private static BigInteger getFibonacciSumSquares(int n) {

        if (n <= 1)
            return BigInteger.valueOf(n);

        BigInteger sum = BigInteger.valueOf(0);
        BigInteger a[] = new BigInteger[n];
        a[0] = a[1] = BigInteger.ONE;
        for (int i = 2; i < n; i++) {
            a[i] = a[i - 1].add(a[i - 2]);
            a[i] = a[i].pow(2);
            sum = sum.add(a[i]);
        }
        return sum;

    }

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();

        System.out.println(getFibonacciSumSquares(n));
    }
}

After accepting the first answer I ran some stress tests on the code snippet and the correction that was needed was an "=" sign in the code. hope that helps. For more details please refer to the answer's comments.

答案1

得分: 1

BigInteger在处理比起Java原始数据类型要慢很多,因此在长范围内请使用原始数据类型。以下是您的代码和结果:

public class FibonacciSumSquares {
    private static BigInteger getFibonacciSumSquares(int n) {
        if (n <= 1)
            return BigInteger.valueOf(n);
        BigInteger sum = BigInteger.ZERO;
        long last = 1, lastTwo = 1, current = 0;
        BigInteger lastBigInteger = BigInteger.ONE;
        BigInteger lastTwoBigInteger = BigInteger.ONE;
        BigInteger currentBigInteger;
        boolean isUsePrimary = true;

        for (int i = 2; i <= n; i++) {
            if (isUsePrimary) {
                current = last + lastTwo;
                current = current * current;
                if (current > (last + lastTwo)) {
                    lastTwo = last;
                    last = current;
                    sum = sum.add(BigInteger.valueOf(current));
                } else {
                    isUsePrimary = false;
                    lastTwoBigInteger = BigInteger.valueOf(lastTwo);
                    lastBigInteger = BigInteger.valueOf(last);
                    currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
                    currentBigInteger = currentBigInteger.pow(2);

                    sum = sum.add(currentBigInteger);
                }
            } else {
                currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
                currentBigInteger = currentBigInteger.pow(2);
                sum = sum.add(currentBigInteger);
            }
        }
        return sum;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        System.out.println(getFibonacciSumSquares(10000));
        System.out.println("used time(ms): " + (System.currentTimeMillis() - start));
        /**
         * 在:MacBook Pro (Retina, 15-inch, Mid 2014)
         *
         * n = 10000
         * 811453295998950457153326378602357232029212
         * used time(ms): 24
         *
         * n = 20000
         * 1623556274380606238932066737816445867589212
         * used time(ms): 32
         *
         * n = 999999
         * 81209566945485034687670444066761210743605656
         * used time(ms): 368
         */
    }
}
英文:

BigInteger runs more slower than java primitive types, so use primitive in long range.
here is my code and result:

public class FibonacciSumSquares {
private static BigInteger getFibonacciSumSquares(int n) {
if (n &lt;= 1)
return BigInteger.valueOf(n);
BigInteger sum = BigInteger.ZERO;
long last = 1, lastTwo = 1, current = 0;
BigInteger lastBigInteger = BigInteger.ONE;
BigInteger lastTwoBigInteger = BigInteger.ONE;
BigInteger currentBigInteger;
boolean isUsePrimary = true;
for (int i = 2; i &lt;= n; i++) {
if (isUsePrimary) {
current = last + lastTwo;
current = current * current;
if (current &gt; (last + lastTwo)) {
lastTwo = last;
last = current;
sum = sum.add(BigInteger.valueOf(current));
} else {
isUsePrimary = false;
lastTwoBigInteger = BigInteger.valueOf(lastTwo);
lastBigInteger = BigInteger.valueOf(last);
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
} else {
currentBigInteger = lastBigInteger.add(lastTwoBigInteger);
currentBigInteger = currentBigInteger.pow(2);
sum = sum.add(currentBigInteger);
}
}
return sum;
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(getFibonacciSumSquares(10000));
System.out.println(&quot;used time(ms): &quot; + (System.currentTimeMillis() - start));
/**
* On: MacBook Pro (Retina, 15-inch, Mid 2014)
*
* n = 10000
* 811453295998950457153326378602357232029212
* used time(ms): 24
*
* n = 20000
* 1623556274380606238932066737816445867589212
* used time(ms): 32
*
* n = 999999
* 81209566945485034687670444066761210743605656
* used time(ms): 368
*/
}

}

huangapple
  • 本文由 发表于 2020年8月26日 16:31:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63593643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定