【问题标题】:Sieve of Eratosthenes prime numbers up to a million c++筛选 Eratosthenes 素数高达一百万 c++
【发布时间】:2015-03-28 18:10:38
【问题描述】:

所以我的代码需要帮助。出于某种原因,当我输入超过 500,000 的数字时,它一直在崩溃。这是确切的任务。

实施埃拉托色尼筛法并用它找出所有素数 小于或等于一百万的数字。使用结果 证明哥德巴赫猜想对四到四之间的所有偶数 一百万,包括在内。

使用以下声明实现一个函数:

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

这个函数接受一个整数数组作为它的参数。数组 应初始化为值 1 到 1000000。 函数修改数组,以便只保留素数; 所有其他值都归零。

必须编写此函数以接受任何整数数组 尺寸。您必须输出 1 到 1000000,但是当我测试你的函数时,它可能在一个数组上 大小不同。

使用以下声明实现一个函数:

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;
            }
        }
    }
}

【问题讨论】:

  • int array[num]; 请改用std::vector&lt;int&gt; array(num);。您的堆栈大小可能太小而无法分配这么大的数组。
  • 我还没有学会如何使用向量。不过谢谢你的回复!
  • 您也可以使用int* array = new int[n]; 自己管理分配的堆内存。但要小心。
  • 请查看these search results

标签: c++ sieve-of-eratosthenes


【解决方案1】:

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

int array[num];

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

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

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

  1. 您将用于程序的堆栈大小配置为足够大以容纳 int 元素的数量(这取决于操作系统)
  2. 您改用std::vector&lt;int&gt; array(num);,它将这些元素分配到堆内存中
  3. 您在程序结束时使用int* array = new int[num];delete [] array; 自己在堆上分配必要的内存(我不推荐这种解决方案,因为在正确的内存管理方面很容易犯愚蠢的错误)李>

【讨论】:

  • 我不明白如何将向量实现到我的程序中。感谢您的回复!
  • @Bawad 如图,并将std::vector::data()作为参数传递给其他函数。
  • @Bawad 哪个错误?你错过#include &lt;vector&gt;了吗?
  • 我不是在玩负鼠先生,哈哈。我只是不明白。我相信你是个很聪明的人。我对编程很陌生。 @πάντα ῥεῖ
  • @Bawad 那么你为什么接受这个答案呢?你的错误是什么?你不明白什么?
【解决方案2】:

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

为什么不使用位数组呢?

做类似的事情

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

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

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

节省大量内存。

EDIT1:

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

EDIT2:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多