【问题标题】:Special Fibonacci and SIGSEGV特殊斐波那契和 SIGSEGV
【发布时间】:2016-05-26 20:30:57
【问题描述】:
#include<bits/stdc++.h>
#define big 1000000007
using namespace std;
long long n,k;
int fobo(int);
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        k=fobo(n)%big;
        printf("%d",k);
        printf("\n");
    }
    return 0;
}
int fobo(int m)
{
    if(m==1)
        return 0;
    if(m==2)
        return 1;
    return 3*fobo(m-1)+2*fobo(m-2)+5;
}

上面的代码用于打印一种特殊类型的斐波那契数列的总和,遵循函数fobo 内的递归关系中给出的关系。该代码在我的机器上运行良好,但在任何在线法官的测试中,相同的代码显示 SIGSEGV 错误。程序中没有使用任何数组,访问我知道的未知内存。我想这些是出现 SIGSEGV 错误的一些主要要求。我在这里找不到任何东西。请帮助我解决或查找错误。

【问题讨论】:

  • hobo(n)fobo?
  • #include&lt;bits/stdc++.h&gt;aaaaaaaaarrrrrrrrrrrggggggggggghhhhhhhhhhhhh
  • long long n,k; /* ... */ scanf("%d",&amp;n); 为什么是long long
  • 从技术上讲,它不是斐波那契数列,而是具有递归关系的数列。斐波那契特指序列 0, 1, 1, 2, 3, 5, 8, 13, ... 其中 a[n] = a[n-1] + a[n-2];甚至卢卡斯数列(2、1、3、4、7、11、18,...)也不是斐波那契数列,因为它使用不同的起始数字。
  • 它在某些国家的竞争性节目中非常受欢迎,它让我发疯。原因如下:stackoverflow.com/q/31816095/560648

标签: c++ recursion fibonacci segmentation-fault


【解决方案1】:

如果我不得不猜测,这看起来像是堆栈溢出错误。尝试将 0 输入 fobo。发生这种情况时,您的基本情况不会触发,因为没有人会检查零。然后调用fobo(-1)fobo(-2),这将启动fobo(-2)fobo(-3)fobo(-4) 等形式的递归调用链,直到最终溢出堆栈。

要解决此问题,请考虑在代码中为 0 添加新的基本情况,或者进行常规检查以处理输入为负数的情况。

编辑:基于 cmets,我认为这里的主要问题是,如果您使用大量输入调用此函数,则会在递归终止之前出现堆栈溢出。为了解决这个问题,请考虑使用动态编程自下而上计算您的值。我怀疑这就是问题最终要解决的问题。或者,使用适合尾调用消除的不同递归公式。如果您不熟悉这些技术,请上网查找 - 您会在此过程中学到很多东西!

【讨论】:

  • 好吧,这是一个大错误。修复 。但仍然获得 SIGSEGV
  • 即使修复了它,如果你用足够大的n 值调用它,它仍然会导致堆栈溢出。尝试在你的机器上测试 n=1000000000...
  • @ChrisDodd 是的,它在我的机器上崩溃了。但是我该如何解决它
  • 你需要以一种不需要太多堆栈空间的方式编写它——要么使用交互方法,要么查找“memoization”和“tail calls”
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
相关资源
最近更新 更多