欧拉筛法判素

素数,又称质数。其特征为除开1和其本身外,没有能将其整除的数。

举个例子,2、3、5均为素数,而4则不为素数(因为2可以将其整除),并且1也不为素数。

那么根据定义可轻松得到代码如下

#include<stdio.h>
int main ()
{
    int num,flag=1;     //flag用以标记状态,为1则认为其为素数,否则则不为素数(默认其为素数)
    scanf("%d",&num); //num即想要判定的数
    for(int i=2;i<num;i++) //自2开始到num-1
    {
        if(num%i==0)    //一旦出现求余结果等于0的情况(即i可以整除num)说明num非素数
        {
            flag=0;     //将flag修改为0,即代表该数不为素数
            break;      //既然已经判定为非素数了,后续的循环再无必要,直接退出节省时间。
        }
    }
    if(flag&&num!=1)    //注意此处num!=1,因为1也不视为素数,但是如果i为1的话flag是不会被修改为0的(for循环的内容根本不会执行)
                        //所以需要我们手动额外增加判定条件
    {
        printf("%d是素数",num);
    }
    else
    {
        printf("%d不是素数",num);
    }
    system("pause");
    return 0;
}

但这个根据定义直接写出的代码非常简单粗暴,但也有弊端,当num(也就是所需要判定的数)过大时,需要消耗很多的时间,循环次数即num-2,即时间复杂度为O(n),当num较大时非常容易超时,所以调用math库下的sqrt函数,可以将时间复杂度压缩为O(\sqrt{n})。

#include<stdio.h>
#include<math.h>
int main ()
{
    int num,flag=1;     //flag用以标记状态,为1则认为其为素数,否则则不为素数(默认其为素数)
    scanf("%d",&num); //num即想要判定的数
    for(int i=2;i<=sqrt(num);i++) //自2开始到根号下num
    {
        if(num%i==0)    //一旦出现求余结果等于0的情况(即i可以整除num)说明num非素数
        {
            flag=0;     //将flag修改为0,即代表该数不为素数
            break;      //既然已经判定为非素数了,后续的循环再无必要,直接退出节省时间。
        }
    }
    if(flag&&num!=1)    //注意此处num!=1,因为1也不视为素数,但是如果i为1的话flag是不会被修改为0的(for循环的内容根本不会执行)
                        //所以需要我们手动额外增加判定条件
    {
        printf("%d是素数",num);
    }
    else
    {
        printf("%d不是素数",num);
    }
    system("pause");
    return 0;
}

而除此之外,也可以使用一个记忆数组,记录所有小于num的素数,只需要遍历这个记忆数组,只要没有出现能将num整除的素数,则可认为该num也是素数,即欧氏筛(由埃氏筛改进而来,此处不多赘述),因为实际上多数情况下非素数的个数远远大于素数的个数,以这个方法能大大减少循环的次数,并且在需要判定多个数是否为素数时可以重复利用,大大节省了时间。代码如下

#include<stdio.h>
int main ()
{
    int a,i,m,flag,len=1;   //len即记忆数组arr的长度
    int arr[1000]={2};      //数组长度由实际情况决定,此处粗略设为1000,同时将首个数据初始化为2(第一个素数为2)
    scanf("%d",&a);         //读入所需要判定的数
    for(m=3;m<=a;m++)       //已将2列入记忆数组,故而此处m从3开始
    {
        flag=1;
     for(i=0;i<len;i++)       //循环判素,但注意此处的循环是对记忆数组arr循环
     {
     if(m%arr[i]==0)
      flag=0;   
     }
     if(flag)
     {
      arr[len++]=m;     //如果当前数为素数,则列入记忆数组,并且记忆数组的长度len加一
     }
    }
    for(i=0;i<len;i++)  //循环输出记忆数组中已记录的素数
    {
        printf("%d是素数\n",arr[i]);
    }
    if(arr[len-1]==a)   //显然如果输入的数为素数,那么记忆数组中所记录的最后一位就应该等于这个数
    {
        printf("%d是素数\n",a);
    }
    else
    {
        printf("%d不是素数\n",a);
    }
   
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值