最近在复习之前做的编程练习题,素数判断一直没有掌握,今天看到了一种新的方法,感觉特别好,记下来。(第一次写博客,很开心呀)
思想来源,看不懂我的,欢迎看原作
素数的一些性质吧
- 素数的分布规律
大于5的素数一定于6的倍数相邻,例如5和7,11和13,17和19等等。 - 证明
令 x ≥ 1,则大于5的自然数可以表示如下:
…….6x-1, 6x, 6x+1, 6x+2, 6x+3, 6x+4, 6x+5,6(x+1)-1………..
可以看到,不在6的倍数的两侧的6x+2, 6x+3, 6x+4,由于上式可表示为2(3x+1), 2(2x+3), 2(3x+2),So 他们一定不是素数,在除去6x本身,显然素数只能出现在6的倍数的两侧,但这只是素数的必要条件可不是充分必要条件,所以在6的倍数的两侧的数也不一定素数。 - 孪生素数
题外话,放个题拿走练练
C++代码实现与解析
明确目的: 找到可以整除的数(这很重要)
实现:
- 首先对两个较小的素数进行处理
- 接下来判断这个数是否在6的倍数的两侧,不是的话直接返回0,是的话接着处理
- 由于一个数N如果可以被另一个数m整除,那m一定小于N的开方,没啥问题。所以我们就取判断的上界为N的开方。为了更快呢,直接取 i 的每次递增6,原因是,假如要判断的数为N,那N一定可以表示为6x-1或6x+1,对于循环中的 i 也可以表示为6的倍数加上或减去个数字,即6m-1,6m,6m+1,6m+2,6m+3,6m+4,如果N能被6m,6m+2,6m+4,整除那N至少是一个偶数,显然第二步已经把偶数排除了,所以不可能成立,而对于6m+3如果成立则N至少是3的倍数,但6x是3的倍数,显然6x+1,6x-1可能被3整除,所以N也不可能被6m+3整除,那现在就只剩下了6m-1,6m+1了,只需判断它俩能否把N整除,如果可以那就存在了一个数可以把N整除,就返回0。反之就不存在了,那就走到了最后就返回1,哈哈大功告成。
bool isPrime(int num)
{
// 两个较小的数另外处理
if(num == 2 || num == 3)
{
return 1;
}
// 不在6的倍数的两侧的一定不是素数
if(num % 6 != 1 && num % 6 != 5)
{
return 0;
}
int tem = (int)sqrt(num);
//在6的倍数的两侧的也不一定是素数
for(int i = 5;i <= tem;i += 6)
{
if(num % i == 0 || num % (i + 2) == 0)
{
return 0;
}
}
// 排除所有剩余的是素数
return 1;
}
人生第一篇博客,如有错误欢迎指正讨论。谢谢我自己,也谢谢大家
写个博客不容易,可怜可怜博主,点个广告再走呗(✿◕‿◕✿)。