c实现的求质数几种方法总结
2014-04-12 02:01
627 查看
质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数).
方法:通常两类,一是试除法,二是筛选法。
一、试除法
1.0
2.0
3.0
4.0
5.0
二、筛选法
6.0
7.0
方法:通常两类,一是试除法,二是筛选法。
一、试除法
1.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数). 试除法1.0 要判断n是否为质数,就从2一直尝试到 n-1。时间复杂度为O(n)。在n非常大或者测试量很大时,这种方法显然是不可取的。 */ bool IsPrime(int n) { int i; for(i = 2; i < n; i++) { if(n %i == 0) return false; } return true; }
2.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 试除法2.0 素数即只能被1和其本身整除的数,判断n是否为素数只需用2~n/2之间的数去除就可以了。因为一个数的一半的平方大于其本身是从5开始的,解方程:n/2的平方>n 。即一个数n的两个因数不能同时比n/2大。就可以说一个数若不是素数则一定在2~n/2之间有因数。而且2,3也是符合下面程序的。 时间复杂度仍然为O(n) */ bool IsPrime(int n) { int i; for(i = 2; i <= (n/2); i++) { if(n %i == 0) return false ; } return true; }
3.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数). 试除法3.0 除了2以外,所有可能的质因数都是奇数。所以就先尝试 2,然后再尝试从 3 开始一直到 x/2 的所有奇数。时间复杂度仍然为O(n) */ bool IsPrime(int n) { int i; if(n % 2 == 0) return false; for(i = 3; i <= (n/2); i+=2) { if(n %i == 0) return false ; } return true; }
4.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数). 试除法4.0 对于一个整数n,需要测试根号n次,所以本算法的时间复杂度为O(√)的。 */ /*通常如下 bool IsPrime(int n) { int i,s; s = sqrt(n); for(i = 2; i <= s; i++) { if(n %i == 0) return false; } return true; } */ /*这里使用i*i<=n来取代i<=√ 是为了避免是用sqrt()函数,其消耗时间很大,在大量数据测试中时间消耗很明显。同时强制转换i成long long类型是为了防止i*i在int范围内溢出。*/ bool IsPrime(int n) { int i; for(i = 2; (long long)i*i <= n; i++) { if(n %i == 0) return false; } return true; } void main() { int n,res,i,k,prime[100]; n = 0 ; k = 0; printf("a prime?yes: 1,no:0 \n"); for(i = 2; i<=100; i++) { res = IsPrime(i); printf("number %d,answer: %d \n",i,res); if(res == 1) { n++; prime[i] = 1; } } printf("the count of prime :%d ",n); printf("\nas follows: \n"); for(i = 2; i <= 100; i++) { if(prime[i]) { printf("%3d ",i); } } }
5.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数). 试除法5.0 对于一个整数n,只需用小于等于√n所有素数去除,所以本算法的时间复杂度为O(√)的。 */ bool IsPrime(int n,int prime[],int length) { int i; for(i = 2; (long long)i*i <= n&&prime[i]; i++) { if(n %i == 0) return false; } return true; }
二、筛选法
6.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数). 筛选法6.0 厄拉多塞筛法,采用了一种与众不同的方法:先将2-N的各数放入表中,然后在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止。 这时,表中画了圈的以及未划去的那些数正好就是小于 N的素数。 */ void IsPrime(int n) { int i,j,a ; for(i = 0; i < n ; i++) { a[i] = i; } for(i = 2; i < n; i++) { if(a[i]) { for(j = 2; i *j< n ; j++) { a[i*j] = 0; } } } for(i = 0; i < n ; i++) { if(a[i]) { printf("%2d ",i); } } } int main() { int n; n= 200000; IsPrime(n); return 0; }
7.0
# include <stdio.h> #include <math.h> #include <stdbool.h> /* 6N±1法 7.0 任何一个自然数,总可以表示成为如下的形式之一: 6N,6N+1,6N+2,6N+3,6N+4,6N+5 (N=0,1,2,…) 显然,当N≥1时,6N,6N+2,6N+3,6N+4都不是素数,只有形如6N+1和6N+5的自然数有可能是素数。 所以,除了2和3之外,所有的素数都可以表示成6N±1的形式(N为自然数)。 */ bool IsPrime(int n); int HowManyPrime(int n) { int i,j,prime ; prime[2] = 1; prime[3] = 1; for( j = 2; j < n; j++) { if( ((j +1) % 6 == 0) || ((j - 1) % 6 == 0) )//在给定范围内,挑出6n±1的数字 { if( IsPrime(j) == true )//将第一步得到的6n±1数组的每个元素用来测试, prime[j] = 1; } } for(i = 0; i < n; i++) { if(prime[i]==1) { printf("%d ",i); } } return 0; } bool IsPrime(int n) { int i; for(i = 2; (long long)i*i <= n; i++) { if(n %i == 0) return false; } return true; } int main() { HowManyPrime(200000); return 0; }
相关文章推荐
- 基于并发服务器几种实现方法(总结)
- 几种常见的载入中、loading页面效果的实现方法总结
- 几种常见的载入中、loading页面效果的实现方法总结
- Android编程实现异步消息处理机制的几种方法总结
- 总结几种Java字符串反转的实现方法
- 【前端】几种实现水平垂直居中的方法总结
- 几种常见的载入中、loading页面效果的实现方法总结
- python中单例常用的几种实现方法总结
- 用django实现redirect的几种方法总结
- 关于Android实现滑动返回的几种方法总结
- 用django实现redirect的几种方法总结
- SQL中实现SPLIT函数几种方法总结(必看篇)
- Android点击Button实现功能的几种方法总结
- asp下用实现模板加载的的几种方法总结 原创
- asp下用实现模板加载的的几种方法总结 原创
- Linux下实现定时器Timer的几种方法总结
- 几种常见的载入中、loading页面效果的实现方法总结
- Android点击Button实现功能的几种方法总结
- Swift-总结单例实现的几种方法
- SQL中实现SPLIT函数几种方法总结(必看篇)