输出素数试除法C语言升级

单个数字判断是否为素数

  • 素数简单来说就是除了1和自己本身无法被其他数整除的数的集合。
  • 那么判断是否为素数我们就有了这样的想法:
    请添加图片描述
  • 比如说我们要判断a是不是素数,我们假设变量a=5
  • 然后我们可以再定义一个变量j从2开始遍历到4。这样一来,用5分别对2,3,4进行取模运算,如果有一个j的值导致5%j等于0,那么就说明5不是素数,由此可见5是一个素数。(j不取1和5是因为任意整数都能被1和本身整除)
int main()
{
	int a = 0;
	int j = 0;
	scanf("%d", &a);
	for (j = 2; j < a; j++)
	{
		if (a % j == 0)
		{
			printf("不为素数");
			break;
		}
	}
	if (j == a)//当判断j递增到与a相等时就说明没有数能整除a,a是素数
		printf("为素数");
	return 0;
}

-判断单个数字是否为素数我们就可以用上述代码来实现。

判断输出一个范围内的素数

  • 会有题目让我们输出一定范围内的素数,比如:请你输出100到200之间的所有素数。
  • 这样的题目我们怎么来实现呢?刚刚的代码只有一个循环,遍历了j,现在我们只要再加一层循环来遍历100到200之间的整数就可以了。

试除法

int main()
{
	int a = 0;
	int count = 0;


	// 外层循环用来获取100~200之间的所有数据,100肯定不是素数,因此i从101开始
	for (a = 101; a <= 200; a++)
	{
		//判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数
		int j = 0;
		for (j = 2; j < a; j++)
		{
			if (a % j == 0)
			{
				break;
			}
		}

		// 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数
		if (j == a)
		{
			count++;
			printf("%d ", a);
		}
	}


	printf("\ncount = %d\n", count);
	return 0;
}
  • 但是上述方法还是较为繁琐,可以进行改进,因为超过a/2的数一定无法整除a,所以我们可以直接省略遍历[a/2,a]之间的数字。
int main()
{
	int a = 0;//
	int count = 0;


	for (a = 101; a <= 200; a++)
	{
		//判断a是否为素数
		//2->a-1
		int j = 0;
		for (j = 2; j <= a / 2; j++)
		{
			if (a % j == 0)
			{
				break;
			}
		}
		//...
		if (j > a / 2)
		{
			count++;
			printf("%d ", a);
		}
	}


	printf("\ncount = %d\n", count);
	return 0;
}
  • 如上的代码可以省去一半的力气,可是这是最省力的办法吗?

  • 不是的,我们可以发现
    请添加图片描述

  • 任何一个可以被[2,a-2]的数整数的数字,都可以拆分成两个数字的乘积,而这两个数字一定分别大于等于sqrt(a),和小于等于sqrt(a),例如上图的6。所以如果a能够被[2, sqrt(a)]之间的任意数据整除,则a不是素数

  • 注:sqrt()是开根号的数学函数需要 #include<math.h>头文件

  • 因此我们可以实现下面的代码

int main()
{
	int a = 0;
	int count = 0;


	for (a = 101; a <= 200; a++)
	{
		//判断a是否为素数
		//2->a-1
		int j = 0;
		for (j = 2; j <= sqrt(a); j++)
		{
			if (a % j == 0)
			{
				break;
			}
		}
		//...
		if (j > sqrt(a))
		{
			count++;
			printf("%d ", a);
		}
	}


	printf("\ncount = %d\n", count);
	return 0;
}
  • 到这里是不是觉得代码很完美了呢?其实还可以再次简化。聪明的你会发现连续的两个素数,除了2和3,再无其他连在一起的素数。因此100到200之间是不会存在连续的两个素数的,所以我们的j变量只需要两个两个递增即可,无需一个一个增。
int main()
{
	int a = 0;
	int count = 0;


	for (a = 101; a <= 200; a += 2)//两个两个增
	{
		//判断a是否为素数
		//2->a-1
		int j = 0;
		for (j = 2; j <= sqrt(a); j++)
		{
			if (a % j == 0)
			{
				break;
			}
		}
		//...
		if (j > sqrt(a))
		{
			count++;
			printf("%d ", a);
		}
	}

	printf("\ncount = %d\n", count);
	return 0;
}
  • 这样一来取得素数的代码就较为完善了,比一开始的的逐个逐个遍历要省事的多了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值