小白教程

 找回密码
 立即注册
查看: 8703|回复: 4

c语言:输入一个正整数n,统计小于n的素数个数

[复制链接]

1

主题

1

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2021-3-3 09:35:25 | 显示全部楼层 |阅读模式
如题,求解,萌新。百度不到
回复

使用道具 举报

1

主题

2

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2021-3-14 13:22:46 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>  //因为要用到sqrt()函数
  3. int main()
  4. {
  5. int i,j,flag;
  6. int n,num=0;   //num记录素数的个数

  7. scanf("%d",&n);   
  8. for(i=1;i<=n;i++)     // 从1到n找数
  9. {
  10. flag=1;           //为1时表示i为素数,为0则表示i不是素数
  11. for (j=2;j<=sqrt(i);j++)  // a/b=c,如果b,c不等,则b,c里面的最小值一定小于sqrt(a),所以判断到sqrt(a)就可以
  12. {
  13. if(i%j==0)    //不是素数,修改标志推出for循环
  14. {
  15. flag=0;
  16. break;
  17. }
  18. }
  19. if(flag==1)      //判断是否是素数,
  20. {
  21. printf("%d为素数。\n",i);
  22. num++;        
  23. }
  24. }

  25. printf("%d",num);
  26. return 0;
  27. }
复制代码
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-3-23 03:21:26 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>  //因为要用到sqrt()函数

  3. int main()
  4. {
  5.     int i,j,flag;
  6.     int n, num = 0;   //num记录素数的个数

  7.     scanf("%d", &n);
  8.     if (n < 2) {
  9.         printf("No prime!\n");
  10.         return -1;
  11.     }
  12.     //for(i = 1; i <= n; i++)     // 从1到n找数
  13.     num = 1; //2 is prime
  14.     printf("%d为素数。\n", 2);
  15.     for(i = 3; i <= n; i = i + 2)     // 从1到n找数
  16.     {
  17.         flag=1;           //为1时表示i为素数,为0则表示i不是素数
  18.         for (j=2;j<=sqrt(i);j++)  // a/b=c,如果b,c不等,则b,c里面的最小值一定小于sqrt(a),所以判断到sqrt(a)就可以
  19.         {
  20.             if(i%j==0)    //不是素数,修改标志推出for循环
  21.             {
  22.                 flag=0;
  23.                 break;
  24.             }
  25.         }
  26.         if(flag==1)      //判断是否是素数,
  27.         {
  28.             printf("%d为素数。\n",i);
  29.             num++;
  30.         }
  31.     }

  32.     printf("%d",num);
  33.     return 0;
  34. }
复制代码
回复

使用道具 举报

0

主题

1

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2021-4-13 02:41:15 | 显示全部楼层
https://github.com/kimwalisch/primesieve   用这个筛法的吧, 速度比较可以, 筛法复杂度在 O(N*lnlnN)  ...  我本子上试了下求 1E12 范围内有 37607912018 个素数, 用时  37.3 秒...
不过指定范围素数个数有 O(N^(2/3 + ε)) 的算法,  仔细写能比这个更快些 ...
回复

使用道具 举报

0

主题

3

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2021-4-16 17:55:13 | 显示全部楼层
  1. 很多年前改写的 intfree 求素数个数的 Pascal 代码,  O(N^(2/3 + ε)),  是比 primesieve 快不少,  
  2. 求 500000000000 以内的素数个数,  primesieve 八线程用时  12.9 秒, 单线程用时 89.8秒,  下面的代码单线程用时 10.8 秒, 就是没写成多线程的...


  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <math.h>
  7.   
  8. #define XPREVN        (64*1024*1024)                /**/
  9. #define XSQRTPREVN    (8*1024)
  10. #define XPREVPI        (4*1024*1024)                /* PI(XPREVN) : 3957809 */
  11. #define XMAXPIX           ((LLong)512 << 30)
  12. #define XMAXNTH        ((LLong)10*1000*1000*1000)    /* NTH( 1E10 ) == 252097800623 */
  13.   
  14. int        *X_small_prime ,  X_pi_small_prime;
  15. int        *X_pi_prev_N   , *X_prev_V;
  16.   
  17. #define XPREVDM        (7)
  18. #define XPREVQ        (2*3*5*7*11*13*17)
  19. #define XPREVPHQ    (1*2*4*6*10*12*16)
  20.   
  21. #ifdef _MSC_VER
  22. #pragma warning( disable : 4244 )
  23. typedef __int64        LLong;
  24. #define LLFmt        "I64d"
  25. #else
  26. typedef long long    LLong;
  27. #define LLFmt        "Ld"
  28. #endif
  29.   
  30. static LLong phiX_p( LLong x , LLong a )
  31. {
  32.     if( a == XPREVDM )
  33.         return x / XPREVQ * XPREVPHQ + X_prev_V[ x % XPREVQ ];
  34.     if( x < X_small_prime[a-1] )
  35.         return 1;
  36.     return phiX_p( x , a - 1 ) - phiX_p( x / X_small_prime[a-1] , a - 1 );   
  37. }
  38.   
  39.   
  40.   
  41. LLong phiX( LLong X )
  42. {
  43.     LLong cubeRootX  , max , len3 , len2 , s , i , k;
  44.     LLong sum , p;
  45.     if( X <= XPREVN )
  46.         return X_pi_prev_N[X];
  47.       
  48.     max   = (LLong)(pow( (double)X , 2./3 ) + 2);
  49.     cubeRootX = (LLong)(pow( (double)X , 1./3 ) + .5);
  50.     if( cubeRootX*cubeRootX*cubeRootX > X )
  51.         --cubeRootX;
  52.     len3 = X_pi_prev_N[cubeRootX];
  53.       
  54.     sum = 0; s = 0; k = max -1 ;
  55.     for( i = len3; ;++i )
  56.     {
  57.         p = X_small_prime[i];
  58.         if( p * p > X ) break;
  59.          
  60.         s += X_pi_prev_N[k] - X_pi_prev_N[(int)((double)X/p)];
  61.         k = (int)((double)X/p);
  62.          
  63.         sum += s;
  64.     }
  65.     len2 = X_pi_prev_N[p-1];
  66.       
  67.     sum = (len2-len3)*X_pi_prev_N[max-1] - sum;
  68.     sum = len3 * (len3-1)/2 - len2 * (len2-1) / 2 + sum;
  69.       
  70.     return phiX_p( X , len3 ) - sum + len3 - 1;
  71. }
  72.   
  73. void initSmallPrime()
  74. {
  75.     char *mark = (char*)calloc(1,XPREVN/2+1);
  76.     int i , j;
  77.     X_small_prime = (int*)calloc(sizeof(int),XPREVPI );
  78.     X_pi_prev_N   = (int*)calloc(sizeof(int),XPREVN+1);
  79.     X_prev_V      = (int*)calloc(sizeof(int),XPREVQ+1);
  80.       
  81.     for( i = 3; i <= XSQRTPREVN; i += 2 )
  82.     {
  83.         if( mark[i/2] ) continue;
  84.         for( j = i*i/2; j <= XPREVN/2; j+=i )
  85.             mark[j] = 1;
  86.     }
  87.     X_small_prime[0] = 2;
  88.     X_pi_small_prime = 1;
  89.     X_pi_prev_N[0] = X_pi_prev_N[1] = 0;
  90.     X_pi_prev_N[2] = 1;
  91.     for( i = 3; i <= XPREVN; i += 2 )
  92.     {
  93.         if( mark[i/2] )
  94.         {
  95.             X_pi_prev_N[i+1] = X_pi_prev_N[i] = X_pi_prev_N[i-1];
  96.         }
  97.         else
  98.         {
  99.             X_pi_prev_N[i+1] = X_pi_prev_N[i] = 1 + X_pi_prev_N[i-1];
  100.             X_small_prime[X_pi_small_prime++] = i;
  101.         }
  102.     }
  103.     free(mark);
  104.       
  105.     for( i = 0; i < XPREVQ; ++i )
  106.         X_prev_V[i] = i;
  107.     for( i = 1; i <= XPREVDM; ++i )
  108.         for( j = XPREVQ-1; j >= 0; --j )
  109.             X_prev_V[j] -= X_prev_V[ j/X_small_prime[i-1] ];
  110. }
  111.   
  112. int main()
  113. {
  114.     LLong a;
  115.     clock_t now = clock();
  116.     initSmallPrime();
  117.     printf( "init time used : %lf seconds\n" , (double)(clock() - now) / CLOCKS_PER_SEC);
  118.   
  119.     while( 1 == scanf( "%" LLFmt , &a ) )
  120.     {
  121.         if( a <= 0 )
  122.             break;
  123.         else if( a <= XMAXPIX )
  124.         {
  125.             now = clock();
  126.             printf( "phiX( %" LLFmt " ) == %" LLFmt "\n" , a , phiX( a ) );
  127.             printf( "phiX time used : %lf seconds\n" , (double)(clock() - now) / CLOCKS_PER_SEC );
  128.         }
  129.         else
  130.             printf( "%" LLFmt " Out of range\n" , a );
  131.     }
  132.       
  133.     return 0;
  134. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-11-24 13:33 , Processed in 0.027623 second(s), 26 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表