求素数

关于求素数

  1.问题描述

     质数又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。然后我们可以选择一个输入范围,例如输入start=100和end=200,然后求出之间所有的素数。

  2.解题思路

    首先呢我们求素数,肯定要用的  for  这个关键字,对这个程序而言,肯定需要用的双层循环来实现。

    外层循环先对我们的 start 到 end 之间的每一个数进行迭代,用变量 i 来表示,显然i的取值范围是"strat  <=   i  <=  end",逐个对其进行检测是否为素数,

    内层循环则依然是对从 strat 到 i 之间的每一个数进行迭代,用  k  依次去除需要判定的整数  i (很明显k的取值范围是2~i) 。如果 i 能被 k 整除的话 ,则表明 i 不是素数,反之则证明是素数。

     代码如下:

#include<stdio.h>
#include<math.h>
#include<Windows.h>
int main()
{
	  int start = 0;
  	  int end = 0;
	  int i = 0;
	  int count = 0;  //对素数的个数进行计数  
	  printf("输入 START 和 END:");
	  scanf_s("%d %d", &start, &end);
	  for (i=start; i<= end; i++)  //对start ~end的每个数进行判断  
	  {
		  int k = 0;
		  for (k = 2; k < i; k++)
		  {
			  if (i%k == 0)  //若取余为零,说明不是素数,跳出对该数判断的循环。  
				  break;
		  }
		  if (k == i)        //要判断的数已经和小于自身的数(不包括1和它本身)全部比较了,均不满足以上条件,说明该数是素数。  
		  {
			  printf("%d  ",i);
			  count++;
		  }
	  }

	  printf("\n一共有%d个素数", count);
	  system("pause");
	  return 0;
}

当然,这只不过是我们最基础的方法,我还能不能把代码进行优化呢?

答案是肯定的,我们可以想到,这些数字中有偶数和奇数之分,偶数当然就不用考虑了,他们肯定不是素数,这样我们就节省了一半的工作量

新代码如下:

#include<stdio.h>
#include<math.h>
#include<Windows.h>
int main()
{
	int start = 0;
	int end = 0;
	int i = 0;
	int count = 0;  //对素数的个数进行计数  
	printf("输入 START 和 END:");
	scanf_s("%d %d", &start, &end);
	if (start % 2 == 0)
		i = start+1;
	else
		i = start ;
	for (i ; i <= end; i+=2)  //对start ~end的每个奇数进行判断  
	{
		int k = 0;
		for (k = 2; k < i; k++)
		{
			if (i%k == 0)  //若取余为零,说明不是素数,跳出对该数判断的循环。  
				break;
		}
		if (k == i)        //要判断的数已经和小于自身的数(不包括1和它本身)全部比较了,均不满足以上条件,说明该数是素数。  
		{
			printf("%d  ", i);
			count++;
		}
	}

	printf("\n一共有%d个素数", count);
	system("pause");
	return 0;
}

关于判断一个具体的数(比如200)是否是素数,不用试除到199。因为任何一个数都可以写成两个数的乘积的形式,由于我们是从2开始试除的,所以2是试除的第一个判断条件。若被2整除,以200为例,即200/2=100,可知100就是试除的极限值,当我们试除的数超过100时,一定是一个小于2的数和试除的数相乘才等于200。

换种说法来讲,2是一个数的次小因数,k/2是这个数的次大因数。所以判断条件可以改为for (k=2; k < i/2; k++); 相对应的,后面的if语句也要做出调整 if (k == i/2)  ;

更近一步来说,num/2也不是最佳的试除极限。num的算术平方根才是最佳试除极限,所以判断语句改为  for (k = 2; i <=sqrt(i);k++);    if语句改为 if (k >sqrt(i)  )   ;

所以更完美的代码如下:

#include<stdio.h>
#include<math.h>
#include<Windows.h>
int main()
{
	int start = 0;
	int end = 0;
	int i = 0;
	int count = 0;  //对素数的个数进行计数  
	printf("输入 START 和 END:");
	scanf_s("%d %d", &start, &end);
	if (start % 2 == 0)
		i = start+1;
	else
		i = start ;
	for (i ; i <= end; i+=2)  //对start ~end的每个奇数进行判断  
	{
		int k = 0;
		for (k = 2; k <= sqrt(i); k++) //比较范围是从2到自身的算术平方根的值  
		{
			if (i%k == 0)  //若取余为零,说明不是素数,跳出对该数判断的循环。  
				break;
		}
         if (k >sqrt(i))      //注意判断条件,从2到根号下num 都不能整除,说明该数是素数。    
		{
			printf("%d  ", i);
			count++;
		}
	}

	printf("\n一共有%d个素数", count);
	system("pause");
	return 0;
}
好了,对于for的学习到这就结束了,如果还有优化或者改正的地方,希望大家多多指教
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值