巨大的斐波那契模数C ++

时间:2017-01-16 15:33:01

标签: c++ algorithm

我试图计算Fn mod m,其中Fn是第n个Fibonacci数。 n可能真的很大,所以以简单的方式计算Fn真的效率不高(矩阵取幂工作)。问题陈述要求我们使用模数的分配属性执行而不用计算Fn: (a + b)mod m = [a mod m + b mod m] mod m

(在有人问我之前,我查找了同样问题的答案。但是,我想回答我的具体问题,因为我没有询问算法解决这个问题)

使用这个以及第n个Fibonacci数只是前两个的总和的事实,我不需要存储Fibonacci数,而只需要计算连续模运算的结果。在这个意义上,我应该有一个大小为n的数组F,其中存储了使用上述属性迭代计算Fn mod m的结果。我已设法使用以下代码解决此问题。然而,在审查它之后,我偶然发现了让我感到困惑的事情。

long long get_fibonacci_huge_mod(long long n, long long m) {

    long long Fib[3] = {0, 1, 1};
    long long result;
    long long index;
    long long period;
    long long F[n+1];
    F[0] = 0;
    F[1] = 1;
    F[2] = 1;

    for (long long i = 3; i <= n; i++) {
      F[i] = (F[i-2] + F[i-1]) % m;
      if (F[i] == 0 && F[i+1] == 1 && F[i+2] == 1) {
        period = i;
        break;
      }
    }


    index = n % period;
    result = F[index];
    return result;

}

此解决方案输出任何n和m的正确结果,即使它们非常大。当n很大时,它可能会有点慢,但我现在并不担心。我有兴趣以这种方式专门解决问题。我将尝试使用矩阵求幂或任何其他更快的算法稍后来解决它。

所以我的问题如下。在代码的开头,我创建了一个大小为n + 1的数组F.然后我使用分布属性迭代计算Fn mod m的数组。写完这个循环后让我感到困惑的一件事是,由于F被初始化为全零,如何正确使用F [i + 2],F [i + 1],如果他们没有&#39;是否已计算?我认为它们被正确使用,因为算法每次输出正确结果。也许这个假设是错的?

我的问题不在于算法本身,我在询问内部循环中的内容。

谢谢

1 个答案:

答案 0 :(得分:1)

这是正确算法的错误实现。让我们先看一下修正后的版本。

long long get_fibonacci_huge_mod(long long n, long long m) {
    long long result;
    long long index;
    long long period = n+1;
    long long sz = min (n+1,m*m+1); // Bound for period
    long long *F = new long long[sz];
    F[0] = 0;
    F[1] = 1;
    F[2] = 1;

    for (long long i = 3; i < sz; i++) {
      F[i] = (F[i-2] + F[i-1]) % m;
      if (F[i] == 1 && F[i-1] == 0) { // we have got back to where we started
        period = i-1;
        break;
      }
    }

    index = n % period;
    result = F[index];
    delete[]F;
    return result;

}

为什么原始代码有效?因为你很幸运由于数组初始化为幸运垃圾,对i + 1和i + 2的检查从未评估为真。结果,这减少了对F(n)的幼稚评价而没有结合周期性。