Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 找到40亿以下所有素数的最快方法_C++_Algorithm_Primes_Sieve Of Eratosthenes - Fatal编程技术网

C++ 找到40亿以下所有素数的最快方法

C++ 找到40亿以下所有素数的最快方法,c++,algorithm,primes,sieve-of-eratosthenes,C++,Algorithm,Primes,Sieve Of Eratosthenes,我试着打印2**32以下的每个素数。现在我用布尔向量来做一个筛子,然后在做筛子后打印出素数。打印出高达10亿的素数只需4分钟。有没有更快的方法??这是我的密码 #include <iostream> #include <cstdlib> #include <vector> #include <math.h> using namespace std; int main(int argc, char **argv){ long long lim

我试着打印2**32以下的每个素数。现在我用布尔向量来做一个筛子,然后在做筛子后打印出素数。打印出高达10亿的素数只需4分钟。有没有更快的方法??这是我的密码

#include <iostream>
#include <cstdlib>
#include <vector>
#include <math.h>

using namespace std;

int main(int argc, char **argv){
  long long limit = atoll(argv[1]);
  //cin >> limit;
  long long sqrtlimit = sqrt(limit);

  vector<bool> sieve(limit+1, false);

  for(long long n = 4; n <= limit; n += 2)
    sieve[n] = true;

  for(long long n=3; n <= sqrtlimit; n = n+2){
    if(!sieve[n]){
      for(long long m = n*n; m<=limit; m=m+(2*n))
        sieve[m] = true;
    }
  }

  long long last;
  for(long long i=limit; i >= 0; i--){
    if(sieve[i] == false){
      last = i;
      break;
    }
  }
  cout << last << endl;

  for(long long i=2;i<=limit;i++)
  {
    if(!sieve[i])
      if(i != last)
        cout<<i<<",";
      else
        cout<<i;
  }
  cout<<endl;
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
长限=环礁(argv[1]);
//cin>>限制;
长-长sqrt极限=sqrt(极限);
向量筛(限值+1,假);

对于(长n=4;n这可能会使速度加快一点:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
    std::vector<unsigned long long> numbers;
    unsigned long long maximum = 4294967296;
    for (unsigned long long i = 2; i <= maximum; ++i)
    {
        if (numbers.empty())
        {
            numbers.push_back(i);
            continue;
        }

        if (std::none_of(numbers.begin(), numbers.end(), [&](unsigned long long p)
        {
            return i % p == 0;
        }))
        {
            numbers.push_back(i);
        }

    }

    std::cout << "Primes:  " << std::endl;
    std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, " "));

    return 0;
}
#包括
#包括
#包括
#包括
int main()
{
std::向量数;
无符号长-长最大值=4294967296;

对于(unsigned long long i=2;i这可能会使其速度加快一点:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
    std::vector<unsigned long long> numbers;
    unsigned long long maximum = 4294967296;
    for (unsigned long long i = 2; i <= maximum; ++i)
    {
        if (numbers.empty())
        {
            numbers.push_back(i);
            continue;
        }

        if (std::none_of(numbers.begin(), numbers.end(), [&](unsigned long long p)
        {
            return i % p == 0;
        }))
        {
            numbers.push_back(i);
        }

    }

    std::cout << "Primes:  " << std::endl;
    std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, " "));

    return 0;
}
#包括
#包括
#包括
#包括
int main()
{
std::向量数;
无符号长-长最大值=4294967296;

对于(unsigned long long i=2;i而言,最快的方法可能是采用预生成的列表

第一批14亿素数可供下载,其中应包括300亿左右的素数


我想,当二进制文件只有几GB时,加载它可能会花费太长的时间。

最快的方法可能是使用预生成的列表

第一批14亿素数可供下载,其中应包括300亿左右的素数


我想,当二进制文件的大小只有几GB时,加载它可能会花费太长的时间。

您有没有对耗时最多的内容进行基准测试?是筛选本身,还是写入输出

加快筛选速度的一个快速方法是停止担心所有偶数。只有一个偶数是素数,您可以对其进行硬编码。这样可以将数组大小减半,如果您遇到物理内存的限制,这将非常有帮助

vector<bool> sieve((limit+1)/2, false);
...
  for(long long m = n*n/2; m<=limit/2; m=m+n)
    sieve[m] = true;
向量筛((限值+1)/2,假);
...

对于(long-long m=n*n/2;m您有没有对什么花费了最多的时间进行基准测试?是筛选本身,还是输出的写入

加快筛选速度的一个快速方法是停止担心所有偶数。只有一个偶数是素数,您可以对其进行硬编码。这样可以将数组大小减半,如果您遇到物理内存的限制,这将非常有帮助

vector<bool> sieve((limit+1)/2, false);
...
  for(long long m = n*n/2; m<=limit/2; m=m+n)
    sieve[m] = true;
向量筛((限值+1)/2,假);
...

对于(long long m=n*n/2;m我在my讨论了生成大量素数的问题,其中我发现前十亿个素数的和是11138479445180240497。我描述了四种不同的方法:

  • 蛮力,使用试算法从2开始测试每个数字

  • 使用2,3,5,7轮生成候选,然后使用强伪素数测试对基数2、7和61进行素数测试;此方法最多只能使用2^32,这对我来说不足以求出前十亿个素数的总和,但对你来说就足够了

  • Melissa O'Neill提出的一种算法,使用嵌入优先级队列中的筛子,速度非常慢

  • 埃拉托斯烯的分段筛,速度非常快,但需要空间来储存筛分底漆和筛子本身


  • 我在my讨论了生成大量素数的问题,其中我发现前十亿个素数的和是11138479445180240497。我描述了四种不同的方法:

  • 蛮力,使用试算法从2开始测试每个数字

  • 使用2,3,5,7轮生成候选,然后使用强伪素数测试对基数2、7和61进行素数测试;此方法最多只能使用2^32,这对我来说不足以求出前十亿个素数的总和,但对你来说就足够了

  • Melissa O'Neill提出的一种算法,使用嵌入优先级队列中的筛子,速度非常慢

  • 埃拉托斯烯的分段筛,速度非常快,但需要空间来储存筛分底漆和筛子本身


  • 打印出前十亿个素数需要4分钟以上。我认为最快的方法是跳过所有你知道不是素数的数字,例如,以
    2
    4
    5
    (5之后)结尾的数字,
    6
    8
    0
    如果10亿只需要4分钟,那么40亿只需要16分钟,与等待答案相比,这还不算太糟糕。一旦你计算了它们,你就再也不需要计算它们了。见鬼,把它们从网络上取下来,处理掉吧!为了减少存储需求每个字节中存储了30个整数的素数或非素数信息。存储整数的素数或非素数只需一位。整数的值由位的位置可知。在每30个整数中,对于N>=1,可能是素数的数字是N*30+1、N*30+7、N*30+11、N*30+13、N*30+17、N*30+19、N*30+23、N*30+29这是对谁能做最好的谷歌搜索的竞争吗?;-)打印出前10亿个素数需要4分钟以上。我认为最快的方法是跳过所有你知道不是素数的数字,例如,以
    2
    4
    5
    (5后)结尾的数字,
    6
    8
    0
    如果10亿只需要4分钟,那么40亿只需要16分钟,与等待答案相比,这还不算太糟糕。一旦你计算了它们,你就再也不需要计算它们了。见鬼,把它们从网络上取下来,处理掉吧!为了减少存储需求每个字节中存储了30个整数的素数或非素数信息。存储整数的素数或非素数只需要一个位。该位的位置知道整数的值。在每30个整数中,对于N>=1,可能是素数的数字是N*30+1,N*30