我是Stackoverflow的新手,请指出任何可以提高问题质量的地方。
我的代码(或者希望完成的目标)是计算大规模斐波那契数在一个相当巨大的m下的模。为了使算法更加高效,我使用了pisano periods。实质上,我计算了m的pisano period,然后通过使用以下关系使余数的计算更加简单:
第n个斐波那契数(模m的余数)的余数等于第k个斐波那契数(模m的余数),其中k=n%p,p为m的pisano period。
为了计算pisano period,我使用以下属性:
如果当前的Fib % m = 0并且迄今为止所有Fib的和% m = 0,则当前Fib的索引是m的pisano period。(注意索引必须大于0)
但是我在这个努力中遇到了问题:为了计算pisano period,我必须计算连续的斐波那契数。当需要计算的斐波那契数的数量变得非常大时,比如100,000,则数据类型long会溢出。
据我所知,任何计算pisano periods的努力都将需要计算fibonacci,因此唯一的解决方案似乎是用其他东西替换long。如果有人对可能的替代品有任何建议,我将不胜感激。
import java.util.*;
public class FibHuge {
public static void main (String [] args) {
Scanner in = new Scanner (System.in);
long num = in.nextLong ();
long mod = in.nextLong();
System.out.println ( getMod(num, mod));
}
private static int getMod (long num, long mod) {
Period per = new Period();
long period = per.getPeriod (mod);
int newFibNum = (int)(num % period);
num = (num % mod);
Integer ia[] = new Integer [per.al.size()];
ia = per.al.toArray (ia);
return ia[newFibNum];
}
}
class Period {
ArrayList <Long> al;
long FNum;
long SNum;
Period () {
al = new ArrayList <Long> ();
FNum = 0;
SNum = 1;
}
private long getFib (long first, long second){
return first + second;
}
long getPeriod (long mod){
boolean bool = true;
long fibcount = 0;
long currentmod = 0;
long fib = 0;
long sum = 0;
while (bool){
if (fibcount <= 1){
currentmod = fibcount % mod;
al.add (currentmod);
sum += fibcount;
}
else {
fib = getFib (FNum, SNum);
FNum = SNum;
SNum = fib;
currentmod = (fib % mod);
al.add (currentmod);
sum += fib;
}
if ( (currentmod == 0 & (sum % mod) == 0) & fibcount > 0){
return fibcount;
}
fibcount++;
}
return mod; //essentially just to satisfy the return condition
}
}