long long fibonacci_fast(long long n) {
long long a[n]{0};
a[0]=0;
a[1]=1;
for(int i=2;i<=n;i++)
a[i]=a[i-1]+a[i-2];
return a[n];
}
计算pisano周期的函数是
long long get_pisano_period(long long n,long long m){
vector<long long> vec{0,1};
for(int i=2;i<=n;i++){
vec.push_back(fibonacci_fast(i)%m);
long c{2};
for(int i=2;i<=n;i++){
if((vec[i]!=0) && (vec[i+1]!=1)){
c++;
}}
return c;
}
在主函数中,我只是输出get_pisano_period(n,m)的输出
答案 0 :(得分:1)
代码尝试根据给定模数和看似极限的方式来评估Pisano周期(斐波纳契数列取模n 的周期),但是存在多个问题。 / p>
在fibonacci_fast
中,a
被声明为可变长度数组,这是C ++中的非标准编译器扩展。它也会被初始化,即使使用C99也需要另一个编译器扩展。在这种情况下,应使用std::vector
。
在同一函数中,a
也在循环中(最后一次迭代)以及返回a[n]
时也被无界访问。
在get_pisano_period
中,还有另一个不确定行为的来源,内循环遍历vec
到n + 1
,而其大小为i + 2
。
逻辑错误也很严重。
fibonacci_fast
在不使用模数的情况下计算的斐波那契数,以便这些值不受限制。
仅在将fibonacci_fast
返回的值推入vec
函数内的get_pisano_period
中之前应用模,但这会生成错误的序列。
考虑到get_pisano_period
中的用法,_fast
名称的fibonacci_fast
部分是一个谎言,因为该函数在外部循环中每次都被调用它会生成(并删除)直到递增的i
为止的所有数字。
此外,以下循环检查每对夫妇的后续值(让我们忽略已提到的UB)并计算非{0, 1}
的夫妇对,而函数应找到重复序列后,立即检查最后两个值和 break 。
如果我们只需要句点并且不需要存储序列以备将来使用,则可以仅存储和更新最后两个数字,而无需使用向量。
long long pisano_period(long long m, long long limit = 2048)
{
long long fib_prev{0}, fib{1};
if ( m < 2 )
return 1;
for (long long count{2}; count < limit; ++count)
{
// Evaluate the next Fibonacci number modulo m without any array or function call
long long fib_next{
(fib_prev + fib) % m
};
// If the sequence is repeating, the loop should stop.
if ( fib == 0 && fib_next == 1 )
return count - 1;
// It stores only the two last values, so it has to update them.
fib_prev = fib;
fib = fib_next;
}
std::cerr << "Warning: limit reached.\n";
return limit;
}
可测试的here。