【问题标题】:Printing prime numbers from 1 through 100打印从 1 到 100 的素数
【发布时间】:2011-07-09 05:21:31
【问题描述】:

此 c++ 代码打印出以下素数:3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97。

但我认为这不是我的书想要的写法。它提到了一些关于数字的平方根的事情。所以我确实尝试将我的第二个循环更改为for (int j=2; j<sqrt(i); j++),但它没有给我所需的结果。

我需要如何将此代码更改为我的书想要的方式?

int main () 
{
    for (int i=2; i<100; i++) 
        for (int j=2; j<i; j++)
        {
            if (i % j == 0) 
                break;
            else if (i == j+1)
                cout << i << " ";

        }   
    return 0;
}

素整数是具有 正好是两个不同的除数, 即1和数字本身。写, 运行并测试一个 C++ 程序 查找并打印所有素数 小于 100。(提示:1 是素数 数字。对于从 2 到 100 的每个数字, 找到余数 = Number % n,其中 n 范围从 2 到 sqrt(number)。 \ 如果 n 大于 sqrt(number),则 number 不能被 n 整除。 为什么?如果任何余数等于 0,则 number 不是素数。)

【问题讨论】:

  • 你指的是什么书?
  • 如果您将来需要生成素数,请查看Sieve of Eratosthenes
  • @Sahat 你的书错了。 1 不是质数。它既不是质数也不是合数。
  • @R..:这肯定会引起我的反对。如果我要费心下载一个包含最多 20 亿个素数的列表并用它来膨胀我的代码,那我就麻烦了,因为我自己计算它们会无聊
  • @R..:我不知道,我可以编写一些非常紧凑的代码来生成它们,我猜二进制大小的断点如果存储为 int(400 字节)最多可能是 100 个素数x86 或 ARM 生成素数是奢侈的,编译器是否真的发出这是另一个问题),源大小的断点更小,但一旦你拉入printf,二进制文件就会变大。字符串文字的问题,如果我们认真对待它(我有点同意我们不必在 4k 级别),也适用于数组,因为您需要在单个“逻辑源代码行”中初始化它们。跨度>

标签: c++ c algorithm primes


【解决方案1】:

虽然这是相对更多的生产级素数生成器,但它仍然适用于查找从 1 到 100 的素数。代码使用Miller-Rabin Primality Test 来实现计算素数。由于它是概率方法,因此精度随着 k 值的增加而增加。虽然重点是代码的可读性而不是速度,但在 AWS r5.2xlarge 实例上,质数到 1,000,000 需要 3.791 秒。

// C++ program to print all primes smaller than or equal to 
// n using Miller-Rabin Primality Test
// Reference: https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
// It is not particularly to optimized 
// since focus is readability
// Compile: g++  -std=c++17 -o prime prime.c++ -ltbb 

#include <execution>
#include <iostream>
#include <math.h>
using namespace std; 

int power(unsigned long int x, unsigned long y, unsigned long p){
    int res = 1;
    x = x % p;
    while (y > 0) {
        if (y & 1)
            res = (res * x) % p;
        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}

bool millerTest(unsigned long d, unsigned long n) {
    unsigned long a = 2 + rand () % (n - 4);

    unsigned long x = power(a, d, n);

    if (x == 1  || x == n - 1)
        return true;

    while (d != n - 1){
        x = (x * x) % n;
        d *= 2;
        if (x == 1) return false;
        if (x == n - 1) return true;

    }
    return false;
}

bool isPrime(unsigned long n, int k) {
    if (n <= 1 || n == 4) return false;
    if (n <= 3) return true;

    unsigned long int d = n - 1;
    while (d % 2 == 0)
        d /= 2;
    for(int i = 0; i < k; i++){
        if (!millerTest(d, n))
            return false;
    }
    return true;
}




int main() 
{ 
    int n = 1000000;
    int k = 200; 
    vector<unsigned long> primeN(n);
    iota(primeN.begin(), primeN.end(), 1);

    vector<bool> isPrimeV(n);



    transform(execution::par,
        primeN.begin(), primeN.end(), 
        isPrimeV.begin(), 
        [k](unsigned long x) -> bool {
            return isPrime(x, k);
        });

    int count = accumulate(isPrimeV.begin(), isPrimeV.end(), 0, [](int d, bool v){
        if (v == true) return d += 1; else return d;
    });
    cout << count << endl;

    return 0; 
} 

【讨论】:

    【解决方案2】:

    如果j 等于sqrt(i),它也可能是一个有效因素,不仅是更小

    要在您的内部循环中迭代并包含sqrt(i),您可以编写:

    for (int j=2; j*j<=i; j++)
    

    (与使用sqrt(i)相比,这样做的好处是不需要转换为浮点数。)

    【讨论】:

    • 不是在每一步计算j*j,你可以使用(j+1)*(j+1)=j*j+2*j+1来保持j*j的运行累加器。我想说让编译器来做,但是这些天我对编译器的信心正在失败......
    • 为了避免溢出,可以使用j &lt;= i/j。不在这里,显然。 :)
    【解决方案3】:

    试试这个。 无需任何额外的内置函数,这很容易。

    #include <iostream>
    
    int prime(int n,int r){
    
      for(int i=2;n<=r;i++){
        if(i==2 || i==3 || i==5 || i==7){
          std::cout<<i<<" ";
          n++;
        } else if(i%2==0 || i%3==0 || i%5==0 || i%7==0)
          continue;
        else {
          std::cout<<i<<" ";
          n++;
        }
      }
    
    }
    
    main(){
    
      prime(1,25);
    }
    

    2,3,5,7 的测试足以达到 120 ,所以 100 就可以了。

    100下面有25个素数,121下面有一个30=11*11

    【讨论】:

    • 你会在发布答案之前测试它吗?
    • 抱歉,我实际上是在 2013 年上大学时发布了这个答案,并且对这个领域完全陌生。我知道这个答案是非常错误的。
    【解决方案4】:

    这本书似乎是“面向工程师和科学家的 C++” 由 Gary Bronson 撰写(谷歌搜索)。
    这是一个可能的答案吗?恕我直言,这令人惊讶。

    我不得不把这个问题(从书中)读了几遍。 我的解释:
    对于 每个 数 N: 2 如何?对于 每个 除数 D:2 如果 D 整除 N,N 不是素数, 如果 D > sqrt(N),N 是素数。

    试一试:

    N = 2, sqrt(2) ≈ 1.41, D = 2, 2 < 1.41 ?  no 2 > 1.41 ? yes 2 is prime.  
    N = 3, sqrt(3) ≈ 1.73, D = 2, 2 < 1.73 ?  no 2 > 1.73 ? yes 3 is prime.  
    N = 4, sqrt(4) = 2.00, D = 2, 2 < 2.00 ?  no 2 > 2.00 ?  no 4 is not prime.  
    N = 5, sqrt(5) ≈ 2.24, D = 2, 2 < 2.24 ? yes 5 % 2 > 0? yes  
                           D = 3, 3 < 2.24 ?  no 3 > 2.24 ? yes 5 is prime.    
    N = 6, sqrt(6) ≈ 2.45, D = 2, 2 < 2.45 ? yes 6 % 2 = 0  2 > 2.45 ? no 6 is not prime.
    

    据我所知,应该是这样找到素数的,
    不用筛子(快得多),
    但是:答案就在问题中!令人惊讶?

    速度? primes 让我们数一下素数(我不会显示代码;): 664579 个质数

    #include "stdafx.h"
    #include <math.h>
    #include <iostream>
    using namespace std;
    int main()
    {
        double rt;
        for (int d = 2, n = 2; n < 100; d = 2, n++)
        {
            for (rt = sqrt(n); d < rt; d++)
                if (n % d == 0) break;
            if (d > rt) cout << n << " ";
        }
        getchar();  // 25 primes :-)
    }
    

    删除了带有(与其他答案一样)素筛的较早答案。
    希望我能很快得到我的下一个“死灵法师”徽章。

    我问过作者:在你的书中:“C++ for E&S” 是关于素数的练习,[xrcs]...[/xrcs]。 七年前,它被问到:SO/q/5200879
    前几天我给出了答案:SO/a/49199435
    你认为这是一个合理的解决方案,或者也许是解决方案。

    他回答:彼得,我从来没有真正想到过具体的解决方案 在我补习题的时候,
    所以我不能说我有你的确切解决方案。 C++ 的乐趣在于可以提出非常有创意的解决方案和出色的代码, 乍一看,您似乎已经做到了。
    感谢您发送它!
    布朗森博士

    我去了https://youtu.be/1175axY2Vvw

    PS。一个筛子:https://pastebin.com/JMdTxbeJ

    【讨论】:

    • 您必须获得 5 票赞成才能获得该徽章!因此,也许您需要添加更多讨论(这里“令人惊讶”的是什么?筛子有什么问题?),与其他答案的速度(或内存占用?)等进行比较。 :)
    • @Will Ness:我忘记了内存占用,它是 nada,即零,这还不错。五票赞成?对于一个真正的死灵法师来说,这至少需要 50 年。
    【解决方案5】:

    找到 100 以内的素数特别好,也很容易:

        printf("2 3 ");                        // first two primes are 2 and 3
        int m5 = 25, m7 = 49, i = 5, d = 4;
        for( ; i < 25; i += (d=6-d) )
        {
            printf("%d ", i);                  // all 6-coprimes below 5*5 are prime
        }
        for( ; i < 49; i += (d=6-d) )
        {
            if( i != m5) printf("%d ", i);
            if( m5 <= i ) m5 += 10;            // no multiples of 5 below 7*7 allowed!
        }
        for( ; i < 100; i += (d=6-d) )         // from 49 to 100,
        {
            if( i != m5 && i != m7) printf("%d ", i);
            if( m5 <= i ) m5 += 10;            //   sieve by multiples of 5,
            if( m7 <= i ) m7 += 14;            //                       and 7, too
        }
    

    100 的平方根是 10,因此 the sieve of Eratosthenes2-3 wheel 的这种演绎只使用了上述素数的倍数 3 不大于 10 -- 即。 57 一个人! -- 以增量方式筛选 100 以下的 6-互质数。

    【讨论】:

      【解决方案6】:

      使用Sieve of Eratosthenes 逻辑,我能够以更快的速度获得相同的结果。

      My code demo VS accepted answer

      比较count, 我的代码完成这项工作所需的迭代次数要少得多。最后检查不同N 值的结果。

      为什么这段代码比已经接受的代码表现更好:

      - 偶数在整个过程中甚至不会检查一次。

      - 内部和外部循环都只在可能的范围内进行检查。没有多余的检查。

      代码:

      int N = 1000; //Print primes number from 1 to N
      vector<bool> primes(N, true);
      for(int i = 3; i*i < N; i += 2){    //Jump of 2
          for(int j = 3; j*i < N; j+=2){  //Again, jump of 2
              primes[j*i] = false;
          }
      }
      if(N >= 2) cout << "2 ";
      for(int i = 3; i < N; i+=2){        //Again, jump of 2
          if(primes[i] == true) cout << i << " "; 
      }
      

      对于N = 1000,我的代码需要 1166 次迭代,接受的答案需要 5287(慢 4.5 倍)

      对于N = 10000,我的代码需要 14637 次迭代,接受的答案需要 117526(慢 8 倍)

      对于N = 100000,我的代码需要 175491 次迭代,接受的答案需要 2745693(慢 15.6 倍)

      【讨论】:

      • 接受答案的第一个解决方案的一个严重问题是它(名义上)在内循环的每次迭代中调用sqrt(i)。一个好的优化器可能会设法优化它。第一个解决方案的另一个严重问题是它从头开始为每个值重新建立素数。任何缓存先前素数信息的解决方案(任何类似筛子的解决方案)都将很快胜过该解决方案——除非范围非常小(例如高达 100)以至于缓存的开销超过了评估成本。对于“高达一百万”,这将是可怕的。
      • 请注意,已接受答案中的第三个解决方案使用了先前素数的缓存 - 这与您的解决方案相比如何?
      • @JonathanLeffler 对于 N = 100000 也慢 4 倍,需要 744435。ideone.com/akoiaP
      • @will...您认为哪些计算是多余的...您能否准确指出?
      • @WillNess 只是想......如果我必须找到从 1 到 10000 或更多的质数,你的代码会发生很大变化吗?关于您的最后一条评论:是的,我的程序是 Eratosthenes 筛子的修改版本,它会在此过程中跳过任何短偶数。
      【解决方案7】:

      我总是用这个(简单快捷):

      #include <iostream>
      using namespace std;
      
      int i,j;
      bool b[101];
      
      int main( )
      {
          for(i=2;i<101;i++){
              b[i]=true;
          }
          for(i=1;i<101;i++){
              if(b[i]){
                  cout<<i<<" ";
                  for(j=i*2;j<101;j+=i) b[j]=false;
              }
          }
      }
      

      这是这段代码的输出: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

      【讨论】:

        【解决方案8】:

        这里是打印所有素数直到给定数 n 的简单代码,

        #include<iostream.h>
        #include<conio.h>
        
        void main()
        {
        clrscr();
        int n,i,j,k;
        cout<<"Enter n\n";
        cin>>n;
        
        for(i=1;i<=n;i++)
        {   k=0;
          for(j=1;j<=i;j++)
          {
            if((i%j)==0)
            k++;
           }
          if(k==2)
          cout<<i<<endl;
        }
        getch();
        }
        

        【讨论】:

          【解决方案9】:

          一个打印“N”个素数的简单程序。您可以使用 N 值为 100。

              #include  <iostream >
              using  namespace  std;
          
              int  main()
              {
                  int  N;
                  cin  >>  N;
                  for (int  i =  2;  N > 0;  ++i)
                  {
                      bool  isPrime  =  true ;
                      for (int  j =  2;  j < i;  ++j)
                      {
                          if (i  % j ==  0)
                          {
                              isPrime  =  false ;
                              break ;
                          }
                      }
                      if (isPrime)
                      {
                          --N;
                          cout  <<  i  <<  "\n";
                      }
                  }
                  return  0;
              }
          

          【讨论】:

            【解决方案10】:

            我是根据 ProdigySim 的第二种方法最流行的答案在 perl 中完成的。我必须在 perl 中添加一个 break 等效项 last,紧跟在 print $i . " \n"; 之后,以避免输出两次素数。

            #!/bin/perl
            use strict;
            
            for(my $i=2; $i < 100; $i++){
            
                my $prime = 1;
            
                for (my $j=2; $j*$j<=$i; $j++){
                    if ($i % $j == 0){
                        $prime = 0;
                        last;
                    }
                    if($prime) {
                        print $i . " \n";
                        last;
                    }
                }
            
            }
            

            【讨论】:

            • 问题是关于 C++ 的。我不确定stackoverflow 关于以不同语言发布解决方案的政策,但您的回答肯定会通过标记perl 使更多人受益。你应该考虑在这里删除它,或者 a) 找到一个类似的 perl 问题,或者 b) 自己发布一个类似的问题,标记它perl,然后用这篇文章回答它。
            【解决方案11】:

            查找是否没有。是否是素数 C++:

            #include<iostream>
            #include<cmath>
            
            using namespace std;
            int main(){
            
            int n, counter=0;
            
            cout <<"Enter a number to check whether it is prime or not \n";
            cin>>n;
            
              for(int i=2; i<=n-1;i++) {
                if (n%i==0) {
                  cout<<n<<" is NOT a prime number \n";
                  break;
                }
                counter++;
                            }
                //cout<<"Value n is "<<n<<endl;
                //cout << "number of times counter run is "<<counter << endl;
                if (counter == n-2)
                  cout << n<< " is prime \n";
               return 0;
            }
            

            【讨论】:

              【解决方案12】:

              这是我在一个简单博客中的方法:

              //Prime Numbers generation in C++
              //Using for loops and conditional structures
              #include <iostream>
              using namespace std;
              
              int main()
              {
              int a = 2;       //start from 2
              long long int b = 1000;     //ends at 1000
              
              for (int i = a; i <= b; i++)
              {
              
               for (int j = 2; j <= i; j++)
               {
                  if (!(i%j)&&(i!=j))    //Condition for not prime
                      {
                          break;
                      }
              
                  if (j==i)             //condition for Prime Numbers
                      {
                            cout << i << endl;
              
                      }
               }
              }
              }
              

              - 查看更多信息:http://www.programmingtunes.com/generation-of-prime-numbers-c/#sthash.YoWHqYcm.dpuf

              【讨论】:

                【解决方案13】:
                #include "stdafx.h"
                #include<iostream>
                using namespace std;
                void main()
                { int f =0;
                 for(int i=2;i<=100;i++)
                  {
                   f=0;
                   for(int j=2;j<=i/2;j++)
                   { 
                     if(i%j==0)
                     { f=1;
                       break;
                     }
                   }
                 if (f==0)
                  cout<<i<<" ";
                }
                 system("pause");
                }
                

                【讨论】:

                • 内循环应该是 j*j 不是吗?
                【解决方案14】:

                这是我对埃拉托色尼筛法的实现(对于 2 和 n 之间的素数)

                #include <iostream>
                
                int main (){
                int n=0;
                std::cout << "n = ";
                std::cin >> n;
                std::cout << std::endl;
                
                if (n==0 || n==1){
                    std::cout << "No primes in this range" << std::endl;
                    return 0;
                }
                
                
                const int array_len = n-2+1;
                
                int the_int_array[array_len];
                for (int counter=2; counter <=n; counter++)
                    the_int_array[counter-2]=counter;
                
                
                int runner = 0;
                int new_runner = 0;
                
                while (runner < array_len ){
                    if (the_int_array[runner]!=0){
                        new_runner = runner;
                        new_runner = new_runner + the_int_array[runner];
                
                        while (new_runner < array_len){
                           the_int_array[new_runner] = 0;
                           new_runner = (new_runner + the_int_array[runner]);
                        }
                    }
                runner++;
                }
                
                runner = 0;
                
                while (runner < array_len ){
                    if (the_int_array[runner]!=0)
                        std::cout << the_int_array[runner] << " ";
                    runner++;
                }
                
                std::cout << std::endl;
                return 0;
                

                }

                【讨论】:

                • 请注意,此代码在int the_int_array[array_len]; 处使用可变长度数组VLA,如果您在编译选项中指定-pedantic,G++ 将承认这是一个非标准扩展。 VLA 是 C99 及更高版本的一个(有用的)特性,但严格来说不是 C++ 的一部分。有一些方法可以解决这个问题 - vector 浮现在脑海中。
                【解决方案15】:

                这是我非常简单的 C++ 程序,用于列出 2 到 100 之间的质数。

                for(int j=2;j<=100;++j)
                {
                    int i=2;
                    for(;i<=j-1;i++)
                    {
                        if(j%i == 0)
                            break;
                    }
                
                    if(i==j && i != 2)
                        cout<<j<<endl;
                }
                

                【讨论】:

                • 请添加一些解释,说明这个程序为什么工作以及它的作用。它可能不会立即显现出来。
                • @AdrianZhang 我认为这是不言而喻的。
                • 这根本不使用平方根优化。
                【解决方案16】:

                实际上更好的解决方案是使用“素数筛或素数筛”,它“是一种快速查找素数的算法”.. wikipedia

                简单(但不是更快)的算法称为“eratosthenes 筛”,可以通过以下步骤完成(再次来自维基百科):

                1. 创建一个从 2 到 n 的连续整数列表:(2, 3, 4, ..., n)。
                2. 最初,让 p 等于 2,即第一个素数。
                3. 从 p 开始,以 p 为增量进行计数,并在列表中标记每个大于 p 本身的数字。这些数字将 2p、3p、4p等;请注意,其中一些可能已被标记。
                4. 在未标记的列表中查找大于 p 的第一个数字。如果没有这样的号码,请停止。否则,让 p 现在等于 这个数字(即下一个素数),然后从第 3 步开始重复。

                【讨论】:

                  【解决方案17】:
                  #include<iostream>
                  using namespace std;
                  void main()
                  {
                          int num,i,j,prime;
                      cout<<"Enter the upper limit :";
                      cin>>num;
                      cout<<"Prime numbers till "<<num<<" are :2, ";
                  
                      for(i=3;i<=num;i++)
                      {
                          prime=1;
                          for(j=2;j<i;j++)
                          {
                              if(i%j==0)
                              {
                                  prime=0;
                                  break;
                              }
                          }
                          if(prime==1)
                              cout<<i<<", ";
                      }
                  }
                  

                  【讨论】:

                  • 这是查找给定数以下素数个数的完美代码。
                  • 不完美之处在于它的时间复杂度,你可以通过将内循环更改为 j*j
                  【解决方案18】:

                  使用可除素数的规则可以在O(n)中找到,真的很有效Rules of Divisibility

                  解决方案将基于数字的各个数字......

                  【讨论】:

                    【解决方案19】:

                    三种方式:

                    1.

                    int main () 
                    {
                        for (int i=2; i<100; i++) 
                            for (int j=2; j*j<=i; j++)
                            {
                                if (i % j == 0) 
                                    break;
                                else if (j+1 > sqrt(i)) {
                                    cout << i << " ";
                    
                                }
                    
                            }   
                    
                        return 0;
                    }
                    

                    2.

                    int main () 
                    {
                        for (int i=2; i<100; i++) 
                        {
                            bool prime=true;
                            for (int j=2; j*j<=i; j++)
                            {
                                if (i % j == 0) 
                                {
                                    prime=false;
                                    break;    
                                }
                            }   
                            if(prime) cout << i << " ";
                        }
                        return 0;
                    }
                    

                    3.

                    #include <vector>
                    int main()
                    {
                        std::vector<int> primes;
                        primes.push_back(2);
                        for(int i=3; i < 100; i++)
                        {
                            bool prime=true;
                            for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++)
                            {
                                if(i % primes[j] == 0)
                                {
                                    prime=false;
                                    break;
                                }
                            }
                            if(prime) 
                            {
                                primes.push_back(i);
                                cout << i << " ";
                            }
                        }
                    
                        return 0;
                    }
                    

                    编辑:在第三个示例中,我们跟踪所有之前计算的素数。如果一个数可以被一个非素数整除,那么还有一些素数

                    【讨论】:

                    • 你可以在第三个例子中改进你的外循环:for (int i=3; i
                    • 我投了反对票:第一个例子不认为 2 和 3 是素数:ideone.com/KeOg7l,因为根本没有进入循环。一般来说,我不认为 break 应该被认为是邪恶的,但是当你将它与像你的 if 语句这样的奇异的循环停止条件结合使用时,我会说它肯定是。此外,我认为您的前两个示例是等效的,除了第二个使用更好的代码实践而第一个是错误。我还建议不要做 sqrt(x)
                    • 内循环中的 j
                    • @hariszaman 防止 i 是素数时出现越界错误
                    • 而不是玩弄状态,goto 到外部循环的末尾就足够了,这正是需要它的那种情况。 if(prime)... 变得多余。
                    【解决方案20】:

                    我使用以下代码(当然使用 sqrt)检查一个数字是否为素数:

                    bool IsPrime(const unsigned int x)
                    {
                      const unsigned int TOP
                      = static_cast<int>(
                          std::sqrt( static_cast<double>( x ) )
                        ) + 1;
                    
                      for ( int i=2; i != TOP; ++i )
                      {
                        if (x % i == 0) return false;
                      }
                      return true;
                    }
                    

                    我使用这种方法来确定素数:

                    #include <iostream>
                    
                    using std::cout;
                    using std::cin;
                    using std::endl;
                    
                    #include <cmath>
                    
                    void initialize( unsigned int *, const unsigned int );
                    void show_list( const unsigned int *, const unsigned int );
                    void criba( unsigned int *, const unsigned int );
                    void setItem ( unsigned int *, const unsigned int, const unsigned int );
                    
                    bool IsPrime(const unsigned int x)
                    {
                      const unsigned int TOP
                      = static_cast<int>(
                          std::sqrt( static_cast<double>( x ) )
                        ) + 1;
                    
                      for ( int i=2; i != TOP; ++i )
                      {
                        if (x % i == 0) return false;
                      }
                      return true;
                    }
                    
                    int main()
                    {
                    
                        unsigned int *l;
                        unsigned int n;
                    
                        cout << "Ingrese tope de criba" << endl;
                        cin >> n;
                    
                        l = new unsigned int[n];
                    
                        initialize( l, n );
                    
                        cout << "Esta es la lista" << endl;
                        show_list( l, n );
                    
                        criba( l, n );  
                    
                        cout << "Estos son los primos" << endl;
                        show_list( l, n );
                    }
                    
                    void initialize( unsigned int *l, const unsigned int n)
                    {
                        for( int i = 0; i < n - 1; i++ )
                            *( l + i ) = i + 2;
                    }
                    
                    void show_list( const unsigned int *l, const unsigned int n)
                    {
                        for( int i = 0; i < n - 1; i++ )
                        {
                            if( *( l + i ) != 0)
                                cout << l[i] << " - ";
                        }
                        cout << endl;
                    }
                    
                    void setItem( unsigned int *l, const unsigned int n, const unsigned int p)
                    {
                        unsigned int i = 2;
                        while( p * i <= n)
                        {
                            *( l + (i * p - 2) ) = 0;
                            i++;
                        }
                    }
                    
                    void criba( unsigned int *l, const unsigned int n)
                    {
                        for( int i = 0;  i * i <= n ; i++ )
                         if( IsPrime ( *( l + i) ) )
                            setItem( l, n, *(l + i) );      
                    }
                    

                    【讨论】:

                      【解决方案21】:

                      可以将 for 循环更改为 for (int j=2; j&lt;=sqrt(i); j++),但您还需要更改其他内容。专门查看您的打印条件,

                      else if (i == j+1) {
                            cout << i << " ";
                      }
                      

                      如果只迭代到sqrt(i),为什么永远不会触发?您可以将cout 移动到哪里来更改此设置? (提示:您可能希望将打印移出循环,然后使用某种类型的标志变量)

                      【讨论】:

                        【解决方案22】:

                        如果一个数有除数,则其中至少一个必须小于或等于该数的平方根。当你检查除数时,你只需要检查到平方根,而不是一直到被测试的数字。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2019-11-16
                          • 1970-01-01
                          • 2021-01-14
                          • 2011-12-20
                          • 1970-01-01
                          相关资源
                          最近更新 更多