编程求出50之内的全部素数(素数的不同求法及在线测试比较)
编程求出50之内的全部素数(素数的不同求法及在线测试比较)bool isPrime(int n) { if(n<2) return false; if(n==2 || n==3) return true; if(n%6 != 1 && n%6 != 5) return false; int bound = sqrt(n) 1; for(int i=5;i<bound;i =6) if(n%i==0 || n % (i 2)==0) // i = 6x-1 i 2 = 6x 1 return false; return true; }5 使用筛选法大于3的质数总是等于6*n 1或6*n 5,其中n是大于等于1的自然数。bool isPrime(int n) { if(n<2)
素数也就是质数。素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。简单说,素数是指只有两个因子(1和它自身)的自然数。
0 按定义求解
#include <stdio.h>
bool isPrime(int n)
{
    int factors = 0;
    if(n<2)
        return false;
    for(int i=2;i<n;i  )
        if(n%i==0)
            factors  ;
    return factors==0;
}
main()
{
    int count = 0;
    for(int i=1;i<1000;i  )
        if(isPrime(i))
            printf("%d\t" i count  );
    printf("\n一共有 %d 个素数\n" count);
    getchar();
}
/*output
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      101     103     107     109     113
127     131     137     139     149     151     157     163     167     173
179     181     191     193     197     199     211     223     227     229
233     239     241     251     257     263     269     271     277     281
283     293     307     311     313     317     331     337     347     349
353     359     367     373     379     383     389     397     401     409
419     421     431     433     439     443     449     457     461     463
467     479     487     491     499     503     509     521     523     541
547     557     563     569     571     577     587     593     599     601
607     613     617     619     631     641     643     647     653     659
661     673     677     683     691     701     709     719     727     733
739     743     751     757     761     769     773     787     797     809
811     821     823     827     829     839     853     857     859     863
877     881     883     887     907     911     919     929     937     941
947     953     967     971     977     983     991     997
一共有 168 个素数
*/
    
1 BF(Brute Force)枚举
没有任何优化的Brute Force方法,在全部可能的解空间中做线性搜索(枚举):
bool isPrime(int n)
{
    if(n<2)
        return false;
    for(int i=2;i<n;i  )
        if(n%i==0)
            return false;
    return true;
}
    
2 限定枚举上界
double sqrt(double n)
{
    double t = n/2;
    while(t*t-n<-1e-5 || t*t-n>1e-5)
        t = (t   n/t)/2;
    return t;
}
bool isPrime(int n)
{
    if(n<2)
        return false;
    int bound = sqrt(n) 1;
    for(int i=2;i<bound;i  ) // a*b = sqrt(n)  必有a或b<=sqrt(n)
        if(n%i==0)
            return false;
    return true;
}
    
3 步长为2
bool isPrime(int n)
{
    if(n==2) return true;
    if(n<2 || n%2 == 0)
        return false;
    int bound = sqrt(n) 1;
    for(int i=3;i<bound;i =2)
        if(n%i==0)
            return false;
    return true;
}
    
4 步长为6
大于3的质数总是等于6*n 1或6*n 5,其中n是大于等于1的自然数。
bool isPrime(int n) 
{
    if(n<2)
        return false;
    if(n==2 || n==3)
        return true;
    if(n%6 != 1 && n%6 != 5)
        return false;
    int bound = sqrt(n) 1;
    for(int i=5;i<bound;i =6)
        if(n%i==0 || n % (i 2)==0) // i = 6x-1  i 2 = 6x   1
            return false;
    return true;
}
    
5 使用筛选法
#include <stdio.h>
#include <malloc.h>
double sqrt(double n)
{
    double t = n/2;
    while(t*t-n<-1e-5 || t*t-n>1e-5)
        t = (t   n/t)/2;
    return t;
}
bool isPrime(int n)
{
    if(n==2) return true;
    if(n<2 || n%2 == 0)
        return false;
    int bound = sqrt(n) 1;
    for(int i=3;i<bound;i =2)
        if(n%i==0)
            return false;
    return true;
}
void filterPrime(int n)
{
    bool *arr = (bool*)malloc(sizeof(bool)*(n 1));
    arr[0] = arr[1] = false;
    for(int i=2;i<=n;i  )
        arr[i] = true;
    for(i=2;i<=n;i  )
        if(arr[i])
            for(int j=2;i*j<=n;j  )
                arr[i*j] = false;
    int count = 0;
    for(i=2;i<=n;i  )
        if(arr[i])
            printf("%d\t" i count  );
    printf("\n一共有 %d 个素数\n" count);
    free(arr);
}
main()
{
    filterPrime(1000);
    getchar();
}
    
在线性能比较:
https://quick-bench.com/q/Nd-_MgmOpYTDHsEqMbI5w1BROQk

输入以下测试代码:
double sqrt(double n)
{
    double t = n/2;
    while(t*t-n<-1e-5 || t*t-n>1e-5)
        t = (t   n/t)/2;
    return t;
}
bool isPrime2(int n)
{
    if(n==2) return true;
    if(n<2 || n%2 == 0)
        return false;
    int bound = sqrt(n) 1;
    for(int i=3;i<bound;i =2)
        if(n%i==0)
            return false;
    return true;
}
bool isPrime6(int n) 
{
    if(n<2)
        return false;
    if(n==2 || n==3)
        return true;
    if(n%6 != 1 && n%6 != 5)
        return false;
    int bound = sqrt(n) 1;
    for(int i=5;i<bound;i =6)
        if(n%i==0 || n % (i 2)==0) // i = 6x-1  i 2 = 6x   1
            return false;
    return true;
}
static void BM_isPrime2(benchmark::State& state) {
    for (auto _ : state) {
        isPrime2(9901);
    }
}
BENCHMARK(BM_isPrime2);
static void BM_isPrime6(benchmark::State& state) {
    for (auto _ : state) {
        isPrime6(9901);
    }
}
BENCHMARK(BM_isPrime6);
    
测试结果:

将未考虑步长,只考虑了边界的代码进行测试:
bool isPrime2(int n)
{
    if(n<2)
        return false;
    int bound = sqrt(n) 1;
    for(int i=2;i<bound;i  ) // a*b = sqrt(n)  必有a或b<=sqrt(n)
        if(n%i==0)
            return false;
    return true;
}
    
测试结果:

-End-




