算法——素数判定方法

原始版素数表


最初刚接触算法的时候,使用了原始的方法来输出素数表:

void originalPrime()
{
    long p, d, input;
    int isPrime;
    
    printf("input a number:");
    scanf("%li", &input);
    
    for (p = 2; p <= input; p++) {
        isPrime = 1;
        for (d = 2; d < p; d++) {
            if (0 == p % d) {
                isPrime = 0;
            }
        }
        if (isPrime) {
            printf("%li\n", p);
        }
    }
}

这个就是简单的for循环嵌套,来寻找素数。
不过这个算法效率比较低,时间复杂是O(n * n!)。

改进版素数表


后来知道了如果一个数是合数,那么它的最大质因子不会大于它的平方根——sqrt(x)。

(质因子的概念
质因子(或质因子)在数论里是指能整除给定正整数的质数。两个没有共同质因子的正整数称为互质。因为1没有质因子,1与任何正整数(包括1本身)都是互质。正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式。只有一个质因子的正整数为质数。)

于是,算法改进了下:

void increPrime()
{
    long p, d, input;
    int isPrime;
    
    printf("input a number:");
    scanf("%li", &input);
    
    for (p = 2; p <= input; p++) {
        isPrime = 1;
        for (d = 2; d <= sqrt(p) ; d++) {
            if (0 == p % d) {
                isPrime = 0;
            }
        }
        if (1 == isPrime) {
            printf ("%li\n", p);
        }
    }
}


这里不再判断d到p的所有值了 ,只到p的平方根即可,速度提升了一些。

筛选法素数判定


还有效率超高的,就是筛选法。
筛选法先初始化一个数组prime[]用来表示是否为素数,里面存放0或1来进行逻辑判断。
先筛选掉所有偶数
for (i = 3; i <= input; i++) {
        if (i % 2 == 0) {
            prime[i] = 0;
        } else {
            prime[i] = 1;
        }
    }


之后的思想是如果i是素数,那么i加任意个i的数则是合数。举一个30以内的例子:
i=3; 由于prime[3]=1, 把prime[6], [9], [12], [15], [18], [21], [24], [27], [30]标为0.
i=4; 由于prime[4]=0,不在继续筛法步骤。
i=5; 由于prime[5]=1, 把prime[10],[15],[20],[25],[30]标为0.

完整的算法:

void primeFilter()
{
    long i, j, input;
    
    printf("input a number:");
    scanf("%li", &input);
    int prime[input + 1];
    
    prime[2] = 1;
    for (i = 3; i <= input; i++) {
        if (i % 2 == 0) {
            prime[i] = 0;
        } else {
            prime[i] = 1;
        }
    }
    for (i = 3; i <= sqrt(input); i++) {
        if (prime[i]) {
            for (j = i + i; j < input; j += i) {
                prime[j] = 0;
            }
        }
    }
    for (i = 2; i <= input; i++) {
        if (prime[i]) {
            printf("%li\n", i);
        }
    }
}

如果输入的数不是很大的时候,那么其实三个算法效果差别不大,但是如果数很大,比如100000,那么输出结果的时间可以相差好几秒。而且筛选法的时间非常快。

你可能感兴趣的:(c,算法)