http://dongxicheng.org/structure/prime/
1. 素数判定问题
素数判定问题是一个非常常见的问题,本文介绍了常用的几种判定方法。
2. 直观判断
素数的定义是,除了能被1和它本身整除而不能被其他任何数整除的数。根据素数定义 只需要用2到n-1去除n,如果都除不尽,则n是素数,否则,只要其中有一个数能整除则n不是素数。
1 bool prime_1(int n){ 2 for(int i=2;i<n;i++){ 3 if(n%i==0) 4 return flase;//不是素数 5 } 6 else 7 return true;//是素数 8 }
3. 直观判断改进
上述判断方法,明显存在效率极低的问题。对于每个数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。C++代码如下:
1 bool prime_2(int n){ 2 for(int i=2;i<=sqrt(n);i++) 3 if(n%i==0) 4 return flase;//不是素数 5 else 6 return true;//是素数 7 }
3. 筛法求素数
更高效地素数判断方法应该是将素数预先保存到一个素数表中,当判断一个数是否为素数时,直接查表即可。这种方法需要解决两个问题:
(1) 怎样快速得到素数表?(采用筛选方法)
(2) 怎样减少素数表的大小?(采用位图数据结构)
对于1到n全部整数,逐个判断它们是否是素数,找出一个非素数,就把它挖掉,最后剩下的就是素数。具体方法是:
<1> 定义is_primer[i] = true;
<2> 从2开始,依次遍历整个primer(直到sqrt(N)),如果primer[i]=true,则primer[n*i]=false
如1,2,3,4,5,6,7,8,9,10,则
从2开始遍历:
primer[2]=true,则primer[4]= primer[6]= primer[8]= primer[10]= false,2的倍数
primer[3]=true,则primer[6]= primer[9]= false,3的倍数
1 #include<stdio.h> 2 #define M 2000000 3 char A[2000000]={"