关于质数

质数求法两种:

一、普通法

//普通法判断少量质数

#include<stdio.h>

bool prime(long long p);

int main()
{
	int n,i;
	long long x;
	while(EOF)
	{
		
	printf("需要判断多少个数!\n") ;
	scanf("%d",&n);
	i=0;
	printf("输入%d个数\n",n) ; 
	while(n--)
	{
		scanf("%d",&x);
		if(prime(x))
			;
		else
		 	i++;
	}
	
	printf("有%d个质数!\n",i);
	
	}
 } 
//当一个数x在根号 x之前没找到因子,那这个数就是质数; 
bool prime(long long p)
{
	
    for(int i=2; i * i <= p; i++)//这里需要加等号,因为 2平方是 4 当需要判断的数是4是不符合循环条件  
	{
        if(p % i == 0)
            return true;//表示合数 
    }
    return false;//表示质数 
}

/*
bool长跟判断句: 

if (逻辑表达式)
{
如果是 true 执行这里;
}
else
{
如果是 false 执行这里;
};
*/ 
注意:

for(int i=2; i * i <= j; i++)
这个循环可能存在时间超时的问题,
k=sqrt(j)
for(int i=2;i<=k;i++)
要是用这个不会时间超时

  • 我也是实在不知道原因;

二、线性筛

//线性筛选质数; 
#include<stdio.h>
int findprime();

int isnotprime[1000]; //long long 范围数组 isnotprime[]会把isnotprime[0] 记录错  但prime不会出现这种情况! (若用true false表真假值最好用bool定义)
long long prime[1000];

int main()
{
	int n;
	n=findprime();
	for(int i=0;i<n;i++)
		printf("质数%d\n",prime[i]);
	return 0;
}

int findprime()
{
		int primeCount=0;
		//=========================================核心 
        for(int i = 2; i <= 1000; i++)
		{     
        	if(!isnotprime[i]) //首位素数为false
            	prime[primeCount++] = i;
            	
            for(int j = 2 * i; j <= 1000; j += i)//标记素数的倍数,使他不再进入循环 
                isnotprime[j] = true;  //非素数标记true不再进入循环      
        } 
        //==========================================
        return primeCount; 
}

/*
核心算法就是:合数的其中一个因子一定是质数,2开始,从小往大, 标记倍数为true; (注意:没标记过的数一定是质数)
其实计算以前以内只需要把根号1000以内的质数挑出,便可剔除1000你内的合数,剩下的就是1000以内的质数了 
*/ 
注意

这个里边在问题提交时 会出现答案错误 可能是质数表打的不完整;真找不出原因;

错误代码就是以下:
用线性筛做:
提交时一直显示答案错;

#include<stdio.h>

int N=1000002;
int isnotprime[1000002]; 
int prime[100030];
int findprime();
int main()
{
	int n,x,q,z,k;
	k=findprime();
	//for(int j=0;j<k;j++)
		//printf("%d ",prime[j]);
	
	while(scanf("%d",&q)!=EOF)
	{
		z=0;
		for(int j=0;j<q;j++)
		{
			getchar();
			scanf("%d",&x);
			for(int i=0;i<k;i++)
				if(x==prime[i])
				{
					z++;
					break;
				}
				
		}		
		printf("%d\n",z);
				
	}
	return 0;
}

int findprime()
{
		int primeCount=0;
		
        for(int i = 2; i <= N; i++)
		{
        	if(!isnotprime[i]) 
            	prime[primeCount++] = i;

            for(int j = 2 * i; j <= N; j += i)
                isnotprime[j] = 1;
        } 
        return primeCount;
}


用普通法写:

#include<stdio.h>
#include<math.h>

int prime(int j);
int main()
{
	int a,n;
	int N;
	while(scanf("%d",&N)!=EOF)
	{
		n=0;
		for(int i=0;i<N;i++)
		{
			getchar();
			scanf("%d",&a);
			if(prime(a))
				n++;
		}
		printf("%d\n",n);	
	}
	return 0;
}

int prime(int j)
{
	//int k;
	//k=(int)sqrt(j);
	for(int i=2;i*i<=j;i++)
	{
		if(j%i==0)
			return 0;
	}
		return 1;
}

像上所说:这样写会时间超时 但用k=(int)sqrt(j);就不会

哭了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值