如何寻找素数

最原始的方法

基本思路:

运用素数的性质——只能被1和本身整除,所以如果从2到n-1(不妨设这个数为n)都不能把n整除,那么n就是素数。

代码如下:

#include<stdio.h>
int main()
{
    int i = 0, n = 0, flag = 0,count1 = 0, count2 = 0;
    for(n = 2; n < 100; n ++)
    {
        flag = 1;
        for(i = 2; i < n - 1; i ++)
        {
            count1 ++;//count1用来计数该循环的循环次数
            if(n % i == 0)
            {
                flag = 0;
                break;//flag=0表示n不是素数
            }
        }
        if(flag == 1)
        {
            printf("%d ", n);
            count2 ++;
        }
    }
    printf("\n%d %d", count1, count2);
    return 0;
}

代码回顾:

在这个运行结果中,count1的值为1108,如果范围不是2~100,是个更大的范围,那么count1将会非常大,导致运行效率降低,因此我们要优化代码。

最原始的方法的进阶

基本思路:

假设n = i * j,那么i和j中必有一个是小于等于根号n的,那么我们的循环就不必到n – 1,而是根号n即可。

代码如下:

#include<stdio.h>
int main()
{
    int i = 0, n = 0, flag = 0,count1 = 0, count2 = 0;
    for(n = 2; n < 100; n ++)
    {
        flag = 1;
        for(i = 2; i * i <= n; i ++)
        {
            count1++;//count1用来计数该循环的循环次数
            if(n % i == 0)
            {
                flag = 0;
                break;//flag = 0表示n不是素数
            }
        }
        if(flag == 1)
        {
            printf("%d ", n);
            count2 ++;//count2用来计数素数的个数
        }
    }
    printf("\n%d %d", count1, count2);
    return 0;
}

代码回顾:

在此代码中,count1 = 235,大幅度的小于原始方法中的count1,可见,我们的代码已经得到了优化,那么,是否还能优化呢?答案是肯定的

最原始的方法的进阶的进阶

基本思路:

2和3是最小的两个素数,且除2和3的倍数都是非素数,那么我们先排除2和3的倍数,就可以省去许多步骤;接着,运用数学中的规律,素数分布于6n+1和6n-1之中,就可以利用这个性质再做简化。

代码如下:

#include<stdio.h>
int main()
{
    int i = 0, n = 0, count1 = 0, count2 = 0;
    for(n = 2; n < 100; n ++)
    {
        int flag = 1;
        if(n == 2 || n == 3)
        {
            count1 ++;
            printf("%d ", n);
            count2 ++;
        }
        else if(n % 2 == 0 || n % 3 == 0)
        {
            count1 ++;
            continue;
        }
        else
        {
            for(i = 5; i * i <= n; i += 6)
            {
                count1 ++;
                if((n % i == 0 && n != i) || (n % (i + 2) == 0 && n / (i + 2) != i))
                {
                    flag = 0;
                    break;
                }
            }
            if(flag)
            {
                printf("%d ", n);
                count2 ++;
            }
        }
    }
    printf("\n%d %d", count1, count2);
    return 0;
}

代码回顾:

在此代码中,count1=91,效率之高无需多言。

自定义函数之原始方法

代码如下:

#include<stdio.h>
int is_prime(int n)
{
    for(int i = 2; i * i <= n; i ++)
    {
        if(n % i == 0)
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    int n = 0, count = 0;
    for(n = 2; n < 100; n ++)
    {
        if(is_prime(n) == 1)
        {
            printf("%d ", n);
            count ++;//count用来计数素数的个数
        }
    }
    printf("\n%d", count);
    return 0;
}

自定义函数之方法进阶

代码如下:

#include<stdio.h>
int is_primer(int n)
{
    if(n <= 1)
    {
        return 0;
    }
    else if(n == 2 || n == 3)
    {
        return 1;
    }
    else if(n % 2 == 0 || n % 3 == 0)
    {
        return 0;
    }
    else
    {
        for(int i = 5; i * i <= n; i ++)
        {
            if(n % i == 0 || n % (i + 2) == 0)
            {
                return 0;
            }
        }
    }
    return 1;
}
int main()
{
    int n = 0, count = 0;
    for(n = 0; n <= 100; n++)
    {
        if(is_primer(n))
        {
            printf("%d ", n);
            count ++;
        }
    }
    printf("\n%d", count);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值