【问题标题】:Print first 1 million primes in 1 sec with constraints program size 50000 bytes and limited Memory在 1 秒内打印前 100 万个素数,程序大小为 50000 字节且内存有限
【发布时间】:2012-06-14 19:41:28
【问题描述】:

我尝试过 Eratosthenes 筛子:以下是我的代码:

void prime_eratos(int N) {
    int root = (int)sqrt((double)N);
    bool *A = new bool[N + 1];
    memset(A, 0, sizeof(bool) * (N + 1));
    for (int m = 2; m <= root; m++) {
        if (!A[m]) {
            printf("%d  ",m);
            for (int k = m * m; k <= N; k += m)
                A[k] = true;
        }
    }

    for (int m = root; m <= N; m++)
        if (!A[m])
            printf("%d  ",m);
    delete [] A; 
}

int main(){

    prime_eratos(179426549);
    return 0;
}

花了一些时间:我的系统中真正的 7.340 秒。

我也尝试过阿特金斯筛法(在某处学习的速度比 埃拉托色尼筛)。

但就我而言,这需要时间:真正的 10.433 秒。

代码如下:

int main(){
    int limit=179426549;
    int x,y,i,n,k,m;
    bool *is_prime = new bool[179426550];

    memset(is_prime, 0, sizeof(bool) * 179426550);

    /*for(i=5;i<=limit;i++){
      is_prime[i]=false;
      }*/
    int N=sqrt(limit);
    for(x=1;x<=N;x++){
        for(y=1;y<=N;y++){
            n=(4*x*x) + (y*y);
            if((n<=limit) &&(n%12 == 1 || n%12==5))
                is_prime[n]^=true;
            n=(3*x*x) + (y*y);
            if((n<=limit) && (n%12 == 7))
                is_prime[n]^=true;
            n=(3*x*x) - (y*y);
            if((x>y) && (n<=limit) && (n%12 == 11))
                is_prime[n]^=true;
        }
    }
    for(n=5;n<=N;n++){
        if(is_prime[n]){
            m=n*n;
            for(k=m;k<=limit;k+=m)
                is_prime[k]=false;

        }
    }
    printf("2   3   ");
    for(n=5;n<=limit;n++){
        if(is_prime[n])
            printf("%d   ",n);
    }
    delete []is_prime;
    return 0;
}

现在,我想知道,没有人能够在 1 秒内输出 100 万个素数。

一种方法可能是:

     I store the values in Array but the program size is limited.

有人可以建议我用更少的时间获得前 100 万个素数的方法

比满足约束的一秒(上面讨论过)?

谢谢!!

【问题讨论】:

  • 即使您不生成它们,您的终端也可能不会在一秒钟内打印 100 万行。
  • 可以是概率的吗? less then a second 也依赖于底层硬件,你可以在旧硬件上拥有一个非常好的算法,然后在新硬件上使用一个糟糕的算法。
  • 你的意思是find前100万个素数,因为我认为你不能打印它们,打印缓冲区很小,作为IO需要一些时间。
  • @wobble 我正在输出一个文件...使用时间 ./a.out > eratos.txt
  • 绝对不清楚您是否实现了目标,如果实现了,如何实现。您接受的答案中的建议只能给您双倍的加速,但您需要 8 倍。请更新您的问题。是什么为你解决了这个问题,starbolin 建议的块输出?

标签: c++ primes sieve-of-eratosthenes sieve-of-atkin


【解决方案1】:

试试

int main()
{
    std::ifstream  primes("Filecontaining1MillionPrimes.txt");
    std::cout << primes.rdbuf();
}

【讨论】:

    【解决方案2】:

    你算错了质数。第百万个素数是 15485863,比你建议的要小很多。

    您可以通过消除筛子中的偶数来加快程序并节省空间。

    【讨论】:

    • 哦是的..抱歉我的错误..谢谢...它的第 1000 万个素数.. :)
    【解决方案3】:

    我知道检查一个数字是否为素数的最快方法是检查复合性,我已经实现了 http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test,并在 RSA 上取得了巨大的成功,它是概率性的,成功程度取决于你多少次运行它。

    【讨论】:

      【解决方案4】:

      第 1 步。不要执行 printf

      第 2 步:购买速度更快的计算机。

      【讨论】:

      • Printf 非常慢...每次调用该函数时,它都必须扫描格式字符串,一次一个字符,查找 % 符号,解释任何格式说明符、宽度等。 Printf 功能强大,但速度较慢。
      • 我学到的是 printf 比 cout 快..可能我弄错了..Newyz thnx :)
      • cout 还必须处理大量的格式和选项。对于快速函数,请查看 puts()。它只是输出一个字符串。没有选项,没有逻辑,等等......只是转储一个字符串,直到它达到 NULL。尽可能简单(快速)。
      • 任何对 I/O 的调用都会将时间交给操作系统,启用任务切换和/或导致内核切换上下文。 I/O 调用将支配您的运行时间。不要在每个素数处输出,将它们保存在数组中并将它们移动到打印缓冲区或以块的形式写入流。
      猜你喜欢
      • 1970-01-01
      • 2012-01-17
      • 2019-08-07
      • 2020-10-16
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      相关资源
      最近更新 更多