求素数的C语言代码优化

为了方便叙述,这里我们举一个例子。求100到200之间的素数。
方法一:判断一个数是否为素数我们首先想到的方法就是用这个数除以1到该数之间的每一个整数,如果都不能整除,那么该数为素数。例如求101是否为素数就让101除以2到100之间的数,都不能整除,所以101为素数。
可得代码:

#include<stdio.h>
int main()
{
    int i=0;
    int j=0;
    for(i=100;i<=200;i++)
    {
        for(j=2;j<i;j++)
        {
            if(i%j==0)
                break;
        }
    if(i==j)
    printf("%d\t",i);
    }
    return 0;
}

得到结果:
这里写图片描述
这里得到的结果正确,但是我们发现这样写的程序计算数字较小的情况可以很快,但是如果我们要判断大数量级的数呢?因此,我们要缩短时间复杂度。
这里得到方法二:我们假设一个数为x,如果该数不是一个素数,那么x一定可以由表达式x=a*b表示,所以当a为2时b可得最大值x/2;当b=2时,a为最大值x/2。因此,我们只需要用x除以2到x/2之间的数即可,如果都不能整除,则说明x为素数 。

#include<stdio.h>
int main()
{
    int i=0;
    int j=0;
    for(i=100;i<=200;i++)
    {
        for(j=2;j<i/2;j++)
        {
            if(i%j==0)
                break;
        }
    if(j==i/2)
    printf("%d\t",i);
    }
    return 0;
}

结果与方法一相同:
这里写图片描述
写到这里,我们觉得代码时间复杂度已经减小,但是由方法二得到启发,我们发现a和b一定相等或者一大一小,那么我们只需要除以较小的数即可,那么较小的数的范围是多少呢?当a=b时,a=sqrt(x),所以我们只需除以2到sqrt(x),判断能否被整除。另外,x如果为偶数,那么x一定不是素数。所以代码,再次被优化。
我们得到方法三:

#include<stdio.h>
#include<math.h>
int main()
{
    int i=100;
    for(i=101;i<=200;i+=2)
    {
        int j=2;
        for(j=2;j<sqrt((double)i);j++)
        {
            if(i%j==0)
            {
                break;                  
            }
        }
            if(j>=sqrt((double)i))
            {
                printf("%d\t",i);
            }

    }
    return 0;
}

结果同样正确:
这里写图片描述
虽然,求素数并不是特别复杂的问题,但是这么一个代码都可以得到不断地优化,这也给我们一些启发,在平时编程中应该多思考,不断寻找更好的方法!

### 计算素数的C语言实现 在C语言中,可以通过多种方式实现素数的计算。以下是几种常见的方法及其具体实现。 #### 方法一:试除法 这种方法通过遍历从2到`n-1`的所有整数来判断是否存在可以整除`n`的数。如果不存在,则认为`n`是一个素数[^1]。 ```c #include<stdio.h> int main() { int n = 0; int count1 = 0; // 统计素数个数 for (n = 100; n <= 200; n++) { int j = 0; for (j = 2; j < n; j++) { if (n % j == 0) { // 如果存在能整除n的数,则跳出循环 break; } } if (j == n) { // 若未找到任何因数,则n为素数 printf("%d\n", n); count1++; } } printf("\ncount1=%d", count1); // 输出统计结果 return 0; } ``` 此方法虽然简单易懂,但由于其时间复杂度较高,在处理较大范围的数据时效率较低。 --- #### 方法二:优化后的试除法(利用平方根) 为了提高效率,可以在外层循环中引入数学库中的`sqrt()`函数,仅需验证从2至√n之间的所有可能因子即可完成判定操作[^2]。 ```c #include <stdio.h> #include <math.h> int main(){ int i, count = 0; for(i = 1; i <= 200; i++){ int j; float flag = sqrt((float)i); if(i == 2 || i == 3){ goto sus; } for(j = 2; j <= (int)flag; j++){ if( (int)(i % j) == 0 ){ break; } else if(j == (int)flag){ sus: count++; printf("%d ", i); break; } } } printf("\n"); printf("一共有%d个素数\n", count); return 0; } ``` 相比原始版本,这种改进显著减少了不必要的迭代次数,从而提升了性能表现。 --- #### 方法三:素数和示例 除了单独打印每一个符合条件的质数之外,还可以进一步扩展功能,比如计算指定区间内所有素数总和等问题[^3]。 ```c #include <stdio.h> // 判断是否为素数的辅助函数 int is_prime(int num) { if(num < 2) return 0; for(int k=2;k<=num/2;k++) if(!(num%k)) return 0; return 1; } int main(){ int sum = 0; // 存储累积的结果 for(int i = 2; i < 100; i ++) if(is_prime(i)) sum += i; printf("sum = %d\n", sum); // 显示最终答案 return 0; } ``` 上述代码片段展示了如何定义一个用于检测单个数值是否属于素数范畴的小型工具函数,并将其应用于更大规模的任务之中,例如累加一定范围内所有的素数值等等。 --- ### 总结 以上三种不同风格但目的相同的解决方案分别适用于初学者理解和实践基础概念以及更高级别的程序员追更高执行速度的需场景下选用合适的技术手段解决问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值