码迷,mamicode.com
首页 > 其他好文 > 详细

判断质数的几种方法

时间:2015-03-12 22:17:57      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:

  根据维基百科定义,质数(Prime number),又称素数,指在大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因数的数)。比1大但不是素数的数称为合数。1和0既非素数也非合数。质数在公钥加密算法(如RSA)中有重要的地位。

  下边将会介绍几种较为常见的判断质/素数的方法:

  1. 法一:最直接也最笨的方法

  法一是按照质数的定义来考虑的,具体程序见下:

 1 //*********************************** method 1 ***********************************//
 2 bool IsPrime::isPrime_1(uint num)
 3 {
 4     bool ret = true;
 5     for (uint i = 2; i < num - 1; i++)
 6     {
 7         if (num % i == 0)
 8         {
 9             ret = false;
10             break;
11         }
12     }
13 
14     return ret;
15 }

  2. 法二:将循环判断次数减少一半(大约)

  对于一个正整数num而言,它对(num/2, num)范围内的正整数是必然不能够整除的,因此,我们在判断num的时候,没有必要让它除以该范围内的数。代码如下:

 1 //*********************************** method 2 ***********************************//
 2 bool IsPrime::isPrime_2(uint num)
 3 {
 4     bool ret = true;
 5     uint ubound = num / 2 + 1;
 6     for (uint i = 2; i < ubound; i++)
 7     {
 8         if (num % i == 0)
 9         {
10             ret = false;
11             break;
12         }
13     }
14 
15     return ret;
16 }

  3. 法三:在法二的基础上继续提高

  对于一个小于num的正整数x,如果num不能整除x,则num必然不能整除num/x (num = num/x * x)。反之相同。我们又知num =√num*√num。 如果n除以大于√num的数,必得到小于√num的商,而小于√num的整数已经在2到√num的整数试过了,因为就没有必要再试(√num, num)范围内的数了。代码如下:

 1 //*********************************** method 3 ***********************************//
 2 bool IsPrime::isPrime_3(uint num)
 3 {
 4     bool ret = true;
 5     uint ubound = sqrt(num) + 1;
 6     for (uint i = 2; i < ubound; i++)
 7     {
 8         if (num % i == 0)
 9         {
10             ret = false;
11             break;
12         }
13     }
14 
15     return ret;
16 }

  4. 法四:考虑偶数的因素

  我们都知道,除了2之外,其他所有的偶数(正整数)全都不是质数,因为它们都能被2整除。代码改进如下:

 1 //*********************************** method 4 ***********************************//
 2 bool IsPrime::isPrime_4(uint num)
 3 {
 4     bool ret = true;
 5     if (num == 2)
 6         return ret;
 7 
 8     // it is no need to consider even numbers larger than 2
 9     if (num % 2 != 0)
10     {
11         uint ubound = sqrt(num) + 1;
12         for (uint i = 2; i < ubound; i++)
13         {
14             if (num % i == 0)
15             {
16                 ret = false;
17                 break;
18             }
19         }
20     }
21     else
22     {
23         ret = false;
24     }
25 
26     return ret;
27 }

  5. 法五:埃拉托斯特尼筛选法

  当我们判断某个取值范围内的素数有哪些的时候,有一个方法非常可行,就是埃拉托斯特尼筛选法。这个算法效率很高,但占用空间较大。

  我们知道,一个素数p只有1和p这两个约数,并且它的约数一定不大于其本身。因此,我们下边方法来筛选出来素数:

  1)把从2开始的、某一范围内的正整数从小到大顺序排列;
  2)剩下的数中选择最小的素数,然后去掉它的倍数

  3)依次类推,直到循环结束。

  程序如下:

 1 //*********************************** method 5 ***********************************//
 2 // find prime numbers between [lower bound, upper bound)
 3 vector<uint> IsPrime::retPrime_5(uint lbound, uint ubound)
 4 {
 5     assert(lbound >= 0);
 6     assert(ubound >= 0);
 7     assert(lbound <= ubound);
 8 
 9     vector<bool> isprime;
10     for (int i = 0; i < ubound; i++)
11         isprime.push_back(true);
12 
13     for (int i = 2; i < ubound; i++)
14     {
15         for (int j = i + i; j < ubound; j += i)
16         {
17             isprime[j] = false;
18         }
19     }
20 
21     vector<uint> ret;
22     for (int i = lbound; i < ubound; i++)
23     {
24         if (i != 0 && i != 1 && isprime[i])
25             ret.push_back(i);
26     }
27 
28     return ret;
29 }

 

  整个程序代码(包括单元测试代码)见Github.

  更多的方法请参见百度文库上的一篇文章

 

判断质数的几种方法

标签:

原文地址:http://www.cnblogs.com/xiehongfeng100/p/4332998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!