美丽的海洋 发表于 2021-3-3 09:35:25

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

如题,求解,萌新。百度不到

江南老顽童 发表于 2021-3-14 13:22:46

#include <stdio.h>
#include <math.h>//因为要用到sqrt()函数
int main()
{
int i,j,flag;
int n,num=0;   //num记录素数的个数

scanf("%d",&n);   
for(i=1;i<=n;i++)   // 从1到n找数
{
flag=1;         //为1时表示i为素数,为0则表示i不是素数
for (j=2;j<=sqrt(i);j++)// a/b=c,如果b,c不等,则b,c里面的最小值一定小于sqrt(a),所以判断到sqrt(a)就可以
{
if(i%j==0)    //不是素数,修改标志推出for循环
{
flag=0;
break;
}
}
if(flag==1)      //判断是否是素数,
{
printf("%d为素数。\n",i);
num++;      
}
}

printf("%d",num);
return 0;
}

王四福 发表于 2021-3-23 03:21:26

#include <stdio.h>
#include <math.h>//因为要用到sqrt()函数

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

    scanf("%d", &n);
    if (n < 2) {
      printf("No prime!\n");
      return -1;
    }
    //for(i = 1; i <= n; i++)   // 从1到n找数
    num = 1; //2 is prime
    printf("%d为素数。\n", 2);
    for(i = 3; i <= n; i = i + 2)   // 从1到n找数
    {
      flag=1;         //为1时表示i为素数,为0则表示i不是素数
      for (j=2;j<=sqrt(i);j++)// a/b=c,如果b,c不等,则b,c里面的最小值一定小于sqrt(a),所以判断到sqrt(a)就可以
      {
            if(i%j==0)    //不是素数,修改标志推出for循环
            {
                flag=0;
                break;
            }
      }
      if(flag==1)      //判断是否是素数,
      {
            printf("%d为素数。\n",i);
            num++;
      }
    }

    printf("%d",num);
    return 0;
}

新的天空 发表于 2021-4-13 02:41:15

https://github.com/kimwalisch/primesieve   用这个筛法的吧, 速度比较可以, 筛法复杂度在 O(N*lnlnN)...我本子上试了下求 1E12 范围内有 37607912018 个素数, 用时37.3 秒...
不过指定范围素数个数有 O(N^(2/3 + ε)) 的算法,仔细写能比这个更快些 ...

小会 发表于 2021-4-16 17:55:13

很多年前改写的 intfree 求素数个数的 Pascal 代码,O(N^(2/3 + ε)),是比 primesieve 快不少,
求 500000000000 以内的素数个数,primesieve 八线程用时12.9 秒, 单线程用时 89.8秒,下面的代码单线程用时 10.8 秒, 就是没写成多线程的...


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define XPREVN      (64*1024*1024)                /**/
#define XSQRTPREVN    (8*1024)
#define XPREVPI      (4*1024*1024)                /* PI(XPREVN) : 3957809 */
#define XMAXPIX         ((LLong)512 << 30)
#define XMAXNTH      ((LLong)10*1000*1000*1000)    /* NTH( 1E10 ) == 252097800623 */

int      *X_small_prime ,X_pi_small_prime;
int      *X_pi_prev_N   , *X_prev_V;

#define XPREVDM      (7)
#define XPREVQ      (2*3*5*7*11*13*17)
#define XPREVPHQ    (1*2*4*6*10*12*16)

#ifdef _MSC_VER
#pragma warning( disable : 4244 )
typedef __int64      LLong;
#define LLFmt      "I64d"
#else
typedef long long    LLong;
#define LLFmt      "Ld"
#endif

static LLong phiX_p( LLong x , LLong a )
{
    if( a == XPREVDM )
      return x / XPREVQ * XPREVPHQ + X_prev_V[ x % XPREVQ ];
    if( x < X_small_prime )
      return 1;
    return phiX_p( x , a - 1 ) - phiX_p( x / X_small_prime , a - 1 );   
}



LLong phiX( LLong X )
{
    LLong cubeRootX, max , len3 , len2 , s , i , k;
    LLong sum , p;
    if( X <= XPREVN )
      return X_pi_prev_N;
      
    max   = (LLong)(pow( (double)X , 2./3 ) + 2);
    cubeRootX = (LLong)(pow( (double)X , 1./3 ) + .5);
    if( cubeRootX*cubeRootX*cubeRootX > X )
      --cubeRootX;
    len3 = X_pi_prev_N;
      
    sum = 0; s = 0; k = max -1 ;
    for( i = len3; ;++i )
    {
      p = X_small_prime;
      if( p * p > X ) break;
         
      s += X_pi_prev_N - X_pi_prev_N[(int)((double)X/p)];
      k = (int)((double)X/p);
         
      sum += s;
    }
    len2 = X_pi_prev_N;
      
    sum = (len2-len3)*X_pi_prev_N - sum;
    sum = len3 * (len3-1)/2 - len2 * (len2-1) / 2 + sum;
      
    return phiX_p( X , len3 ) - sum + len3 - 1;
}

void initSmallPrime()
{
    char *mark = (char*)calloc(1,XPREVN/2+1);
    int i , j;
    X_small_prime = (int*)calloc(sizeof(int),XPREVPI );
    X_pi_prev_N   = (int*)calloc(sizeof(int),XPREVN+1);
    X_prev_V      = (int*)calloc(sizeof(int),XPREVQ+1);
      
    for( i = 3; i <= XSQRTPREVN; i += 2 )
    {
      if( mark ) continue;
      for( j = i*i/2; j <= XPREVN/2; j+=i )
            mark = 1;
    }
    X_small_prime = 2;
    X_pi_small_prime = 1;
    X_pi_prev_N = X_pi_prev_N = 0;
    X_pi_prev_N = 1;
    for( i = 3; i <= XPREVN; i += 2 )
    {
      if( mark )
      {
            X_pi_prev_N = X_pi_prev_N = X_pi_prev_N;
      }
      else
      {
            X_pi_prev_N = X_pi_prev_N = 1 + X_pi_prev_N;
            X_small_prime = i;
      }
    }
    free(mark);
      
    for( i = 0; i < XPREVQ; ++i )
      X_prev_V = i;
    for( i = 1; i <= XPREVDM; ++i )
      for( j = XPREVQ-1; j >= 0; --j )
            X_prev_V -= X_prev_V[ j/X_small_prime ];
}

int main()
{
    LLong a;
    clock_t now = clock();
    initSmallPrime();
    printf( "init time used : %lf seconds\n" , (double)(clock() - now) / CLOCKS_PER_SEC);

    while( 1 == scanf( "%" LLFmt , &a ) )
    {
      if( a <= 0 )
            break;
      else if( a <= XMAXPIX )
      {
            now = clock();
            printf( "phiX( %" LLFmt " ) == %" LLFmt "\n" , a , phiX( a ) );
            printf( "phiX time used : %lf seconds\n" , (double)(clock() - now) / CLOCKS_PER_SEC );
      }
      else
            printf( "%" LLFmt " Out of range\n" , a );
    }
      
    return 0;
}
页: [1]
查看完整版本: c语言:输入一个正整数n,统计小于n的素数个数