Fibonacci n modulo m

时间:2016-09-21 02:23:48

标签: java arrays algorithm fibonacci

我正在尝试计算模数,其中可能非常巨大:高达10 ^ 18,是第n个斐波纳契数 这是我的代码,适用于小数字,但对于大数字,它会抛出OutOfMemoryError或NegativeArraySizeException。

import java.util.*;

public class FibonacciHuge {
private static long getFibonacciHugeFast(long n, long m) {
long[] arr = new long[(int) n + 1];
arr[0] = 0;
arr[1] = 1;
for (int i = 2; i < n + 1; i++) {
arr[i] = (arr[i - 1] + arr[i - 2]) % m;
}
return arr[(int) n];
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long n = scanner.nextLong();
long m = scanner.nextLong();
System.out.println(getFibonacciHugeFast(n, m));
}
}

3 个答案:

答案 0 :(得分:1)

以下是对两个例外/错误的解释。

  1. OutOfMemoryError异常:由于您正在尝试创建一个巨大的数组,远远超过可能的大小。请参阅此问题Do Java arrays have a maximum size?
  2. NegativeArraySizeException:由于您将long转换为整数(代码long[] arr = new long[(int) n + 1];)。阅读:Primitive data types。 (基本上你在某个时候溢出,结果整数是负数)

答案 1 :(得分:1)

如果n可以 10 ^ 18 ,那么即使您不使用数组,它仍然会超时,因为您要运行循环直到{{ 1}}( 10 ^ 18 )来计算第n个斐波纳契数。

您可以使用矩阵求幂方法(线性递归方法)。您可以在this博客中找到详细的说明和程序。运行时间为n

希望这有帮助!!!

答案 2 :(得分:1)

您的代码存在两个问题

  1. 你只需要知道斐波那契元素n-1和n-2就可以计算元素n,所以你不需要一个数组而只需要两个变量。
  2. 您可以从n-1和n-2个元素模m计算第n个元素的模m,因为(a + b)%m ==(a%m + b%m)。事实上,你不能长时间存储10 ^ 18个斐波纳契数,因为它的价值很大 - 斐波那契数列呈指数增长。 你可能遇到的唯一问题是,如果%m + b%m溢出,那么你应该将m限制为Long.MAX_VALUE / 2,因为你不知道实际元素的大小ñ。或者,您可以在函数中添加溢出检查。