判断素数的四种方法
傻瓜方法
思路:按照素数的定义,除了1和它本身没有其他的因数,就是素数。
#include<stdio.h>
int main()
{
int i,n;
while(scanf("%d",&n)!=EOF)
{
for(i=2;i<n;i++)
if(n%i==n)
break;
if(i==n)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
缺点:n稍微大点,运行时间就会很长,容易时间超限。
普通解法
思路:比如6,23和32效果是一样的,所以只需对它的前一半进行进行判断就可以了。
#include<stdio.h>
#include<math.h>
int main()
{
int k,i,n;
while(scanf("%d",&n)!=EOF)
{
k=sqrt(n);
for(i=2;i<k;i++)
if(n%i==n)
break;
if(i==k)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
缺点:效率虽提高不少,但n稍微大点,运行时间还是会很长。
普通筛选法(埃拉托斯特尼筛法)
思路:所使用的原理是从2开始,将每个素数的各个倍数,标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。(百度)
#include<stdio.h>
int a[1000001]={0};//全局数组,初始化为0,便于后面标记
int main()
{
long i,j,n;
for(i=2;i<=1000000;i++)
if(a[i]==0)
for(j=i+i;j<=1000000;j+=i)//一个素数的倍数,是一个素数本身为公差的等差数列,所以每次加i
a[j]=1;//将一个素数的倍数标记为1
while(scanf("%ld",&n)!=EOF)
{
if(a[n]==0&&n!=1)//1不是素数
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
理解:比如开始时i=2,那么2的倍数就一定不是素数,所以标记所有2的倍数,同理,3是素数,3的倍数就不是素数,标记为1,当i=4的时候,因为之前被标记过,所以if语句不成立,跳过。
缺点:比如6,在i=2时已经被标记过一遍了,而在i=3时又被标记了一遍,所以还是可以改进。
线性筛法(欧拉筛法)
思路:改进的普通筛法,比如在普通筛法中,6会在2,3的时候被标记两次,而用线性筛法会避免这种问题,因为当i=3的时候,j是从9往后标记的,避免了重复标记。
#include<stdio.h>
int a[1000001];
int main()
{
long i,j,n;
for(i=2;i<=1000000;i++)
if(a[i]==0)
for(j=i*i;j<=1000000;j+=i)
a[j]=1;
while(scanf("%ld",&n)!=EOF)
{
if(a[n]==0&&n!=1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}