std :: map似乎找到了不存在的元素

kin*_*gW3 1 c++ fibonacci

所以,我试图创建一个简单的程序来计算国防部第n个Fibonacci数10^9+7使用倍增公式F[0]=0F[1]=1.程序似乎可以在我的计算机上使用编译器VS2010和CodeBlocks与MinGW一起工作但是在ideone上测试我的程序会为每个输入返回0.似乎在第一次迭代之后,F.find(n)实际上找到了不应该存在的元素.这是我的代码(在VS2010中,我刚刚更改了包含).

#include <bits/stdc++.h>

using namespace std;
std::map<unsigned long long,unsigned long long> F;
unsigned long long fib(unsigned long long n)
{
    if(n==-1) return 0; // Shifting index by 1
    if(n==0) return 1;
    if(n==1) return 1;
    if(F.find(n) != F.end()) return F[n]; // This seems to be the problem,
    else
    {
        if(n%2==0) //
        {
            F[n/2-1] = fib(n/2-1)%1000000007;
            F[n/2] = fib(n/2)%1000000007;
            return F[n] = (F[n/2-1]*F[n/2-1]+F[n/2]*F[n/2])%1000000007;
        }
        else
        {
            F[n/2] = fib(n/2)%1000000007;
            F[n/2+1] = fib(n/2+1)%1000000007;
            return F[n] = (F[n/2]*(2*F[n/2+1]-F[n/2]))%1000000007;
        }
    }
}
int main() {
    unsigned long long int broj; 
    cin >> broj; // input the number
    cout << fib(broj-1) << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Sla*_*ica 9

你有这样的表达式的问题:

F[n/2-1] = fib(n/2-1)%1000000007;
Run Code Online (Sandbox Code Playgroud)

由于没有定义operator[]on 的评估顺序,std::map它可以在之前调用它fib(n/2-1)并在那里创建一个空元素.您应该将缓存值存储在计算它的函数中.

同样std::map::operator[]key你使用的方式打电话也std::map::find很浪费.

可能的修复:

   auto p = F.emplace( n, 0 );
   if( p.second ) { 
       // element was not there
       // calculate and store at p.first->second
   }
   return p.first->second;
Run Code Online (Sandbox Code Playgroud)

  • @RSahu一个查找这个插入,另一个内部`fib(n/2-1)`如何避免第二个? (2认同)