求质数总结
2011-12-04 20:31
225 查看
质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
一、判断一个数是否为质数
首先根据定义,最简单的判断一个数n是否为质数的方法,就是从2开始对小于n的所有数,依次判断是否能整除n,若都不能整除就是质数。
上面是过滤掉了2的倍数,计算量变为原来的二分之一,我们也可以把3的倍数过滤掉,也就是只判断3是否能整除n,其它3的倍数就不需要判断了,计算量就可以变为原来的三分之一。也就是只剩6*k+1和6*k+5(k为整数)这些数,因为其他数都含有因子2或3,n若不能被2或3整除,那么n也不能被6*k,6*k+2,6*k+3,6*k+4这些数整除,就不需要判断这些数能否整除n了,这样又减少了判断量。
二、找出区间内的所有质数
要求区间内的所有质数,首先可以用以上判断单个质数的方法挨个寻找,但是太慢了。。。
这类问题主要的就是筛选法了。筛法求质数的主要思想就是,从小到大,当判断完一个数K是否为质数后,把后面的所有的K的倍数(含因子K)都去掉。
若求两个大数之间的质数,也可以用筛法
如求N1和N2之间的质数1000000000 <= N1 < N2 < 2^32 and 1 < N2 - N1 < 1000000
一、判断一个数是否为质数
首先根据定义,最简单的判断一个数n是否为质数的方法,就是从2开始对小于n的所有数,依次判断是否能整除n,若都不能整除就是质数。
bool IsPrime(int n) { if(n == 1) return false; for(int i = 2; i < n; i++) if(n % i ==0) return false; return true; }我们再稍微改进一下,我们可以先判断一下2能不能整除n,然后2以上的偶数就不需要再判断了,因为2不能整除n那么含有因子2的数肯定也不能整除n。再者,我们根本不需要循环到n,若两个数的乘积为n,那么肯定有一个因子是小于sqrt(n)的,所以,循环的上限可以取sqrt(n)。于是就有:
bool IsPrime(int n) { if(n == 2) return true; if(n == 1 || (n & 1)) return false; int k = (int)sqrt(n); for(int i = 3; i <= k; i += 2) if(n % i == 0) return false; return true; }
上面是过滤掉了2的倍数,计算量变为原来的二分之一,我们也可以把3的倍数过滤掉,也就是只判断3是否能整除n,其它3的倍数就不需要判断了,计算量就可以变为原来的三分之一。也就是只剩6*k+1和6*k+5(k为整数)这些数,因为其他数都含有因子2或3,n若不能被2或3整除,那么n也不能被6*k,6*k+2,6*k+3,6*k+4这些数整除,就不需要判断这些数能否整除n了,这样又减少了判断量。
bool IsPrime(int n) { if((n == 2) || (n == 3)) return true; if((n == 1) || ((n & 1) == 0) || ((n % 3) ==0)) return false; int k = (int)sqrt(n); int step = 4; for(int i = 5; i <= k; i += step) { if(n % i == 0) return false; step = 6 - step; } return true; }
二、找出区间内的所有质数
要求区间内的所有质数,首先可以用以上判断单个质数的方法挨个寻找,但是太慢了。。。
这类问题主要的就是筛选法了。筛法求质数的主要思想就是,从小到大,当判断完一个数K是否为质数后,把后面的所有的K的倍数(含因子K)都去掉。
#define N 1000000 bool isPrime ; int i; memset(isPrime, true, sizeof(isPrime)); isPrime[1] = false; //筛掉大于2的偶数 for(i = 4; i < N; i += 2) isPrime[i] = false; int bound = sqrt(N); //用sqrt(N)以内的质数去筛掉后面含有质数因子的元素 for(i = 3; i <= bound; i += 2) { //从3开始的奇数,如果是质数就去筛掉以自己为因子的元素,不是质数跳过 if(false == isPrime[i]) continue; int step = i << 1; //i为质数,则从i*i开始筛,以2*i为步长(因为偶数已被筛掉,小于i*i的非质数,已被小于i的质数筛掉) for(int j = i * i ; j < N ; j += step) //含有质数因子i,筛掉 isPrime[j] = false; }
若求两个大数之间的质数,也可以用筛法
如求N1和N2之间的质数1000000000 <= N1 < N2 < 2^32 and 1 < N2 - N1 < 1000000
bool isPrime[1000000]; int prime[70000]; //保存小于65536的质数(可以筛unsigned int范围内的数),筛法求出 int primeCnt; //小于65536的质数个数 int i, j; /* 求小于65536的质数,保存在prime数组中 */ int N1 = 100000000; int N2 = 101000000; int D = N2 - N1; memset(isPrime, true, sizeof(isPrime)); for(i = 0; i < primeCnt; i++) { int k = N2 % prime[i]; //可知 N2-k 含质因子prime[i],不是质数,N2 - k - x*prime[i](x为整数)都不是质数数,筛掉 int step = prime[i]; int j = D - k; // N2 - k 对应于数组下标 D - k, N2 - k - x * prime[i] 对应于数组下标 j - x * prime[i]; while(j >= 0) { isPrime[j] = false; //isPrime[j] 代表 N1 + j 是否是质数 j -= step; } }
相关文章推荐
- 算法:“求质数”的题目(总结篇)
- 计算小于n的质数个数 方法总结
- 质数问题总结
- 由一定范围的质数的输出问题所得break、continue总结。
- c实现的求质数几种方法总结
- 9大排序算法的深度总结
- JFreeChart的总结
- 设计模式总结
- 前台基础的校验总结
- 安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中)
- Java泛型总结
- NSNotificationCenter应用总结
- 数据库视频总结(二)
- java基础学习总结——static关键字
- Java第一周总结(20160801-20160807)
- 史上最全的HTML、CSS知识点总结,浅显易懂。
- selenium webdriver 学习总结-浏览器启动方式
- Delphi 常用控件之TlistView总结
- 5、Hive的一些技巧总结
- PHP 页面跳转到另一个页面的多种方法方法总结