当前位置: 首页 > 知识库问答 >
问题:

筛选埃拉托色尼素数高达一百万c

茹康裕
2023-03-14

所以我的代码需要帮助。由于某种原因,当我输入超过500,000的数字时,它总是崩溃。这是确切的分配。

实现埃拉托斯特尼筛,并用它来查找所有小于或等于一百万的素数。使用结果来证明哥德巴赫猜想对于 400 万到 100 万之间的所有偶数(包括 100 万)。

使用以下声明实现函数:

void sieve(int array[], int num);

此函数采用整数数组作为其参数。数组应初始化为值 1 到 1000000。该函数修改数组,以便仅保留质数;所有其他值均归零。

必须将此函数编写为接受任何大小的整数数组。您必须输出 1 到 10000000 之间的所有素数,但是当我测试您的函数时,它可能位于不同大小的数组上。

使用以下声明实现函数:

void goldbach(int array[], int num);

此函数采用与前一个函数相同的参数,并显示4到1000000之间的每个偶数整数,其中包含两个质数。

这里的目标是提供高效的实现。这意味着在确定一个数字是否为素数时,没有乘法、除法或模。这也意味着第二个函数必须有效地找到两个素数。

程序的输出:

1到1000000之间的所有质数,4到1000000之间的所有偶数,以及总和的两个质数。

请勿为此项目提供输出或会话记录!

这是我目前所知道的。如果有人能帮我,那就太好了。

#include <iostream>
using namespace std;

void sieve (int array[], int num);

int main()
{
    int num;
    cout << "Enter a number to calculate up to." << endl;
    cin>> num;
    if ( num < 2 )
        return 0;

    int array[num];
    array[0]= array[1]= 0;
    for ( int i= 2; i < num; ++i )
        array[i]= i;
    sieve(array,num);
    for (int i=0; i<num; i++)
        if (array[i] > 0)
            cout << array[i] <<" "<<endl;
    cout<<endl;

    return 0;
}

void sieve( int array[], int num )
{
    for ( int i= 0; i < num; ++i )
    {
        if ( array[i] != 0 )
        {
            for ( int j= i+i; j < num; j += i )
            {
                array[j]= 0;
            }
        }
    }
}

共有2个答案

施选
2023-03-14
匿名用户

正如我看到的,这是一个作业,您需要编写自己的代码,但我有一些想法可以显着减少内存量。

为什么不使用位数组呢?

做一些像

#define IS_SET(x) (arr[(x)>>3] & (0x01 << ((x) & 0x07)))
#define SET(x) (arr[(x)>>3] |= (0x01 << ((x) & 0x07)))

并将arr定义为字符的数组。这将使内存利用率降低8倍。对于C语言,您可以使用bool可能无法获得尽可能低的内存使用率。

首先清除所有char元素。然后对于每个数字集位,使用SET(x)一次完成所有标记。如果IS_SET(x)评估为false,则x是素数。

节省大量内存。

编辑1:

另一个减少50%所需内存的技巧是不为偶数保留空间。从< code>i=3开始,始终使用< code>i =2递增,并标记位数组。阅读时也这样做。

编辑2:

如果你能找到一个跳过两个或三个或两者的倍数的整数的序列,那么你可以节省大约30%的内存。实际上,您可以制作这样的系列,并跳过存储和标记2和3的倍数或两者的倍数。

尚棋
2023-03-14

代码崩溃的原因是您在这里对数组使用了VLA分配

int array[num];

它用于分配堆栈的< code>num int元素,堆栈很可能太小,无法容纳一百万个< code>int值。

您应该注意,它不是标准的c特性,而是由许多编译器实现提供的扩展。

要解决这个问题,有三种选择:

  1. 您将用于程序的堆栈大小配置为足够大以容纳int元素的数量(这是操作系统依赖的)
  2. 您使用标准::矢量

 类似资料:
  • 我正在尝试让我的埃拉托斯特尼筛程序仅输出用户请求的前n个素数。Sieve本身工作得很好 - 它正确地输出了前100个素数(如下面的数组所示),但是最后一个循环中的计数器变量无法正常工作,我无法找出原因。例如,如果用户输入“5”表示 n,则只会打印前 3 个定焦值。 有人可以帮我找出我的错误吗?我的目的是让“count”成为一个非常简单的计数器,每次都会增加1,直到它达到n。

  • 就像这个问题一样,我也在厄拉多塞的筛子上工作。同样来自《c语言编程原理和实践》一书的第4章。我能够正确地实现它,并且它的功能完全符合练习的要求。 现在,我怎样才能在输入的中处理真正的大数字?类型应该允许我输入2^32=4,294,967,296的数字。但是我不能,我运行内存溢出。是的,我已经计算过了:存储2^32量的int,每个32位。所以32/8*2^32=16 GiB的内存。我只有4 GiB…

  • 我有一个< code >无符号int的位数组< code>prime[]。我希望用这个数组实现一个厄拉多塞筛,让每一位代表一个数。也就是说,给定< code>n,保存对应于< code>n的位的数组元素将是< code>prime[n/32],并且特定位将在位置< code>n2中。 我的函数在数字为素数时返回1(如果其位==0),否则返回0: 我的< code>setBit(int n)函数只是

  • 我在我的一个班级里做的一个作业,我们必须实现一个厄拉多塞的筛子。我已经尝试了七次来得到一个有效的代码,并且尝试了整合我研究过的许多解决方案。我终于有一个可以输出数字的了。不幸的是,它同时打印合数和质数,但不打印2。 我的代码如下: 我怀疑我的循环有问题。我修复了前两个循环的和变量,以便它从2开始打印出来,问题似乎是在我将数组初始化为true后,它没有将合数标记为。 提前感谢你的帮助。

  • 我试图找到素数使用厄拉多塞筛位数组,但我使用的是无符号整数数组。我需要能够产生多达2,147,483,647个素数。我的代码工作正常,可以生成大约10,000,000个,但是当我增加数组的大小以容纳更大的数字时,它失败了。有人能指导我如何用c语言(不是c语言)使用位向量吗?谢谢 这是我的代码:

  • 我正在尝试对厄拉多塞的筛子进行并行实现。我做了一个布尔列表,对于给定的大小,用true填充。无论何时发现一个素数,该素数的所有倍数在布尔列表中都被标记为假。 我试图使这个算法并行的方法是在仍然过滤初始质数的同时启动一个新线程。例如,算法从素数 = 2 开始。在 for 循环中,当素数 * 素数时,我做另一个 for 循环,其中检查素数 (2) 和素数 * 素数 (4) 之间的每个数字。如果布尔列表