C语言笔记:筛选法求质数(适用于求解大范围内数里面质数的个数)

原文链接: http://c.biancheng.net/c/

问题描述:
输入一个整数n(<=100),求1~n之间的所有质数并且输出,并且按每行5个输出

问题分析:
求一个范围内的质数个数,按传统方法是外层做一个循环(循环控制变量为i),取出这个范围的每一个数i;内层再做一个循环(循环控制变量为j),依次判断这个数i%[2,i-1]否为为0,若i在[2,i-1]这个区间有一个数除的尽,则i这个数不是质数。对于1~n(用户输入)每个数都会做一次内层循环判断,且当n越大时,内外层循环嵌套的运算数量也越大,效率低下。

基于这种情况,出现了筛选法的应用,可以避免重复的,不必要的循环,循环次数大大降低。直接看代码:

#include <stdio.h>
#include <string.h>
#define N 100
int main(void)
{
 int prime[N+1];//prime[i]的值为0表示i在筛子上,值为1表示不在筛子上
 int n;//输入30,求1~n之间的质数(可随意) 
 scanf("%d",&n);
 memset(prime,0,sizeof(prime));//将prime中所有的元素值清0
 prime[1]=1;//默认1不是质数
 for(int i=2;i*i<=n;i++)
 {
  if(prime[i]==0)
  {
   for(int j=2*i;j<=n;j+=i)//筛去i的2倍(i*2,该语句仅执行一次),3倍(j+=i),4倍(j+=i)…,这些数肯定不是质数(因为i除了被1和自身整除外,还能被它自身倍数整除)。 
   {
    prime[j]=1;
   }
  } 
 }
 int t = 0 ;   //统计质数个数,以控制每行输出5个
 for(int i = 1; i <= n; i++) 
 {
  if(prime[i] == 0)   //i是质数,则输出,计数,一行输出5个
  {
   printf("%-2d ", i);
   t++;
   if(t%5 == 0) printf("\n"); //一行已输出5个
  }
 } 
 return 0; 
} 

输出:
在这里插入图片描述
以上代码求2~30之间的质数的模拟过程:

  • 当i=2:prime[2]=0(即2是质数,数组下标即对应我们要操作的数),prime[4],prime[6],prime[8]…prime[30]置成1。(即在2~30范围内,2对应的倍数的数都不是质数)

  • 当i=3:由于prime[3]=0,把prime[6],prime[9],…prime[27],prime[30]置成1

  • 当i=4:由于prime[4]=1,不继续筛选步骤。因为4不是质数,因为4已经作为因子2的倍数被筛选掉

  • 当i=5:由于prime[5]=0,把prime[10],prime[15],prime[20],prime[25],prime[30]置成1。

  • 当i=6:6>sqrt(30)算法结束(即6*6>30)。

猜你喜欢

转载自blog.csdn.net/weixin_42124234/article/details/102288780