您的位置:首页 > 其它

c实现的求质数几种方法总结

2014-04-12 02:01 627 查看
质数:一个自然数,如果只有1和它本身两个约数,这个数叫做质数(也称素数).
方法:通常两类,一是试除法,二是筛选法。
一、试除法
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: