【问题标题】:can anyone tell me why the fibonacci function does not work?谁能告诉我为什么斐波那契函数不起作用?
【发布时间】:2021-03-23 07:05:20
【问题描述】:

我想让它每次添加一个尚未找到的参数到地图中,但是当我尝试高于 47 的数字时,它会给我负数,这显然是不可能的

#include <map>
using namespace std;


//memoization
map<unsigned int, unsigned int> memo;
map<unsigned int, unsigned int>::iterator it;
int fibonacci(int n)
{   
    it = memo.find(n);
    if (it != memo.end())
    {
        cout << it->first<<endl;
        return memo.at(n);
    }
    if (n <= 2)
    {
        return 1;
    }
    memo.insert({ n, fibonacci(n - 1) + fibonacci(n - 2) });
    cout << "----"<<n<<endl;
    return memo.at(n);
}
int main()
{
    cout<<fibonacci(48);
}

【问题讨论】:

  • 你查过FIBO(40)的结果吗?unsigned int用袖珍计算器能容纳的最大值吗?
  • 什么是“igni”??
  • @πάνταῥεῖ 袖珍计算器?我意识到“你应该先完成 x、y、z 对我来说简单的事情”的被动攻击版本 cmet 风靡一时,但是,真的,一个袖珍计算器?我们正在将其简化到 级别?
  • 我通常只是用谷歌搜索,找到前 300 个斐波那契数列:http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html
  • @drescherjm 现在 Google 将开始向您展示基于数学的广告。

标签: c++ fibonacci


【解决方案1】:

首先,让我们处理负数。上面的评论解释说你有一个 32 位 int 溢出。

但是,如果不将计算的无符号 int 转换为从该函数返回的 signed,则可以进一步扩展代码。

解决方案是使用更大的类型,例如 unsigned long long int,AKA uint64_t

更新

在接受的答案中有些事情不是最理想的。

  1. 正如我在评论中指出的那样,代码搜索地图两次:it = memo.find(n);memo[n];;应该只返回it-&gt;second;
  2. 该映射中的键无需为 64 位宽; 32 位足以溢出 64 位斐波那契。
  3. 由于映射键的顺序并不重要(您只进行插入/查找),unordered_map 的性能会更好(恒定时间而不是对数)。
  4. 您可能会注意到memo 是按顺序填写的,并由索引访问。这里更好的容器是vector,具有“免费”插入和查找功能。
  5. 调用函数不应该填写memo,因为这不关它的事。

这是我的版本:

#include <vector>
#include <iostream>

//memoization
static std::vector<uint64_t> memo = { 0, 0, 1 };
uint64_t fibonacci(unsigned int n) {
  if (n < memo.size())
    return memo[n];

  memo.push_back(fibonacci(n - 1) + fibonacci(n - 2));
  return memo[n];
}
int main() {
  std::cout << fibonacci(32'000);
}

【讨论】:

  • 非常感谢你,我试过了,你建议我,它有效
  • 那么你应该接受答案...如果你对解决方案感到满意
【解决方案2】:

但是当我尝试高于 47 的数字时,它给了我负数, 显然不可能

unsigned int 大小是 {0 到 4,294,967,295},第 48 斐波那契是 4,807,526,976

固定代码

#include <map>
#include <iostream>
#include <cstdint>
using namespace std;


//memoization
map<int64_t , int64_t> memo;
map<int64_t , int64_t>::iterator it;
int64_t fibonacci(int64_t n) {
    it = memo.find(n);
    if (it != memo.end()) {
        return it->second;;
    }
    memo.insert({n, fibonacci(n - 1) + fibonacci(n - 2)});
    return memo[n];
}
int main() {
    memo.insert({0, 0});
    memo.insert({1, 1});
    memo.insert({2, 1});
    cout << fibonacci(50);
}

【讨论】:

  • 旁注:无符号 int 可以小到 16 位 (0-65535),大到(但不大于)long。而long 可以是从 32 位到与long long 相同的任何大小。而long long 至少为 64 位,并且(此时)没有指定的最大值。没有保证的固定大小,只有最小值。当您需要保证时,您需要使用从 C 中掠夺的 fixed width integers
  • 您正在搜索您的地图两次:it = memo.find(n);memo[n];;应该只返回it-&gt;second;
猜你喜欢
  • 2012-12-29
  • 1970-01-01
  • 2014-05-03
  • 2011-11-19
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多