zoukankan      html  css  js  c++  java
  • 求质数两个方法的好坏分析(是否易懂,操作次数,运算复杂度时间)

     方法1:
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <malloc.h>
     4 #include <stdbool.h>
     5 
     6 int main()
     7 {
     8     long i,j,n,ans=0;
     9     //vis[x]若为true,则代表质数,若为false,则不是质数
    10     bool *vis=(bool *) malloc (sizeof(bool)*100000001);
    11     long *zhi=(long *) malloc (sizeof(long)*10000000);
    12     scanf("%ld",&n);
    13     for (i=2;i<=n;i++)
    14         vis[i]=true;
    15     for (i=2;i<=n;i++)
    16         if (vis[i])
    17         {
    18             ans++;
    19             zhi[ans]=i;
    20             //若大于i的数能被i整除,则该数不是质数
    21             for (j=i;j<=n;j+=i)
    22                 vis[j]=false;
    23         }
    24     printf("%ld
    ",ans);
    25     return 0;
    26 }

     方法2:

        

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 //判断i是否质数,需要判断i能否被(long)sqrt(i)以内的数整除
     5 //若i能被其中一个质数整除,则i不是质数;否则i是质数
     6 
     7 int main()
     8 {
     9     //n=10 ans=4
    10     //n=100 ans=25
    11     //n=1000 ans=168
    12     //n=10000 ans=1229
    13     //n=100000 ans=9592
    14     //n=1000000 ans=78498
    15     //n=10000000 ans=664579
    16     //n=100000000 ans=5761455
    17     long i,j,n,flag,ans=1,t=1;
    18     long *zhi=(long *) malloc (sizeof(long)*10000000);
    19     scanf("%ld",&n);
    20     zhi[0]=2;
    21     for (i=3;i<=n;i++)
    22     {
    23         //若"zhi[t]*zhi[t]==i"成立,则i不是质数,不用继续判断
    24         //且大于i的数需要用zhi[t]判断(j=0;j<t+1;j++)
    25         //这个方法比"当质数大于(long)sqrt(i)时退出"速度快
    26         //而(zhi[t]-1)*(zhi[t]-1)<=i<=n
    27         //当i小于longint范围都能实现
    28         if (zhi[t]*zhi[t]==i)
    29         {
    30             t++;
    31             continue;
    32         }
    33         flag=1;
    34         for (j=0;j<t;j++)
    35             if (i%zhi[j]==0)
    36             {
    37                 flag=0;
    38                 break;
    39             }
    40         if (flag)
    41         {
    42             zhi[ans]=i;
    43             ans++;
    44         }
    45     }
    46     printf("ans=%ld
    ",ans);
    47     /*
    48     for (i=0;i<ans;i++)
    49         printf("%ld ",zhi[i]);
    50     printf("
    ");
    51     */
    52     /*
    53     if (zhi[ans]==n)
    54         printf("%ld is a prime
    ",n);
    55     else
    56         printf("%ld is not a prime
    ",n);
    57     */
    58     return 0;
    59 }

    方法1中,所有被n以内素数(2,3,5,…)整除的 小于等于n的数,都被标记为非素数。

    如: 2——4,6,…… false    (n/2个)

         3——6,9,…… false  (n/3个)

            ……

    其中k为小于等于n的最大的素数,r为欧拉常数,约为0.5772。

    即该方法的时间复杂度为n*log(n),实际上远小于此。

    N

    100

    1000

    10000

    10,0000

    100,0000

    1000,0000

    1,0000,0000

    Log(n)

    4.61

    6.91

    9.21

    11.51

    13.82

    16.12

    18.42

    部分操作次数

    196

    2294

    25529

    275992

    2932206

    30794896

    320798736

    运行时间

     

     

     

     

    15ms

    218ms

    2937ms

    方法2中,n以内的每个数k通过判断能否被sqrt(k)以内的质数整除来判断能否为质数

    N

    100

    1000

    10000

    10,0000

    100,0000

    1000,0000

    1,0000,0000

    Log(n)

    4.61

    6.91

    9.21

    11.51

    13.82

    16.12

    18.42

    部分操作次数

    292

    3892

    54632

    851818

    14991536

    296709390

    6425932861

    运行时间

     

     

     

     

    46ms

    906ms

    19435ms

    相比起方法2,方法1编写更简易明了,而程序的计算更简单很多(方法2的运算是%,*,而方法1的运算是+),运算次数也更很多,所以运行时间也短很多。综上所述求质数方法1更优。

    调试程序:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <malloc.h>
     4 #include <stdbool.h>
     5 #include <time.h>
     6 
     7 int main()
     8 {
     9     clock_t start,finish;
    10     start=clock();
    11     //long long total=0;
    12     long i,j,n=100000000,ans=0;
    13     //vis[x]若为true,则代表质数,若为false,则不是质数
    14     bool *vis=(bool *) malloc (sizeof(bool)*100000001);
    15     long *zhi=(long *) malloc (sizeof(long)*10000000);
    16     //scanf("%ld",&n);
    17     for (i=2;i<=n;i++)
    18         vis[i]=true;
    19     for (i=2;i<=n;i++)
    20         if (vis[i])
    21         {
    22             ans++;
    23             zhi[ans]=i;
    24             //若大于i的数能被i整除,则该数不是质数
    25             for (j=i;j<=n;j+=i)
    26                 vis[j]=false;
    27             //total=total+n/i+1;
    28         }
    29     printf("%ld
    ",ans);
    30     //printf("total=%lld
    ",total);
    31     finish=clock();
    32     printf("time=%.lfms
    ",(double)(finish-start));
    33     return 0;
    34 }
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 //判断i是否质数,需要判断i能否被(long)sqrt(i)以内的数整除
     5 //若i能被其中一个质数整除,则i不是质数;否则i是质数
     6 
     7 int main()
     8 {
     9     //n=10 ans=4
    10     //n=100 ans=25
    11     //n=1000 ans=168
    12     //n=10000 ans=1229
    13     //n=100000 ans=9592
    14     //n=1000000 ans=78498
    15     //n=10000000 ans=664579
    16     //n=100000000 ans=5761455
    17     long i,j,n,flag,ans=1,t=1;
    18     long *zhi=(long *) malloc (sizeof(long)*10000000);
    19     scanf("%ld",&n);
    20     zhi[0]=2;
    21     for (i=3;i<=n;i++)
    22     {
    23         //若"zhi[t]*zhi[t]==i"成立,则i不是质数,不用继续判断
    24         //且大于i的数需要用zhi[t]判断(j=0;j<t+1;j++)
    25         //这个方法比"当质数大于(long)sqrt(i)时退出"速度快
    26         //而(zhi[t]-1)*(zhi[t]-1)<=i<=n
    27         //当i小于longint范围都能实现
    28         if (zhi[t]*zhi[t]==i)
    29         {
    30             t++;
    31             continue;
    32         }
    33         flag=1;
    34         for (j=0;j<t;j++)
    35             if (i%zhi[j]==0)
    36             {
    37                 flag=0;
    38                 break;
    39             }
    40         if (flag)
    41         {
    42             zhi[ans]=i;
    43             ans++;
    44         }
    45     }
    46     printf("ans=%ld
    ",ans);
    47     /*
    48     for (i=0;i<ans;i++)
    49         printf("%ld ",zhi[i]);
    50     printf("
    ");
    51     */
    52     /*
    53     if (zhi[ans]==n)
    54         printf("%ld is a prime
    ",n);
    55     else
    56         printf("%ld is not a prime
    ",n);
    57     */
    58     return 0;
    59 }

     一个更好的方法:

    复杂度O(n)

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <malloc.h>
     4 #include <stdbool.h>
     5 #include <memory.h>
     6 
     7 int main()
     8 {
     9     bool *vis=(bool *) malloc (sizeof(bool)*100000000);
    10     long *zhi=(long *) malloc (sizeof(long)*10000000);
    11     long n=1000,ans,i,j;
    12     memset(vis,true,sizeof(vis)*(n+1));
    13     vis[2]=true;
    14     ans=0;
    15     for (i=2;i<=n;i++)
    16     {
    17         if (vis[i])
    18         {
    19             ans++;
    20             zhi[ans]=i;
    21         }
    22         //对于
    23         for (j=1;j<=ans;j++)
    24         {
    25             if (i*zhi[j]>n)
    26                 break;
    27             vis[i*zhi[j]]=false;
    28             if (i%zhi[j]==0)
    29                 break;
    30         }
    31     }
    32     printf("%ld
    ",ans);
    33     for (i=1;i<=ans;i++)
    34         printf("%ld ",zhi[i]);
    35     printf("
    ");
    36     return 0;
    37 }
  • 相关阅读:
    11.菜单(一)
    线性表之顺序存储详解
    SVN 撤回已提交的代码
    线性表1
    顶层父类
    异常类之派生类
    new和delete重载
    异常类之基类
    Qt中多线程问题
    智能指针实例
  • 原文地址:https://www.cnblogs.com/cmyg/p/6623558.html
Copyright © 2011-2022 走看看