c++/c语言:一篇文章带你走进素数 5种方法AC代码(判断素数,筛法求质数……)

什么是素数(质数)?

质数(素数)是指在大于1的自然数中,除了1和它本身以外不再有其他因数自然数

废话不多说,直接上模版:

bool isPrime(int n){
    for(int i=2;i*i<n;i++)
        if(n%i==0){
            return false;
            break;
        }
    }
    return true;
}

T1:判断质数

说明

质数是指除了1和本身之外没有其他约数的数,如7和11都是质数,而6不是质数,因为6除了约数1和6之外还有约数2和3。
输入一个正整数,判断它是否为质数,如是质数则输出“Yes”,否则输出“No”。

输入格式

一行一个正整数n

输出格式

如是质数则输出“Yes”,否则输出“No”。

样例
输入数据 1
2009
输出数据 1
No
输入数据 2
2
输出数据 2
Yes

F1:暴力函数判断质数

bool isPrime(int n){
    for(int i=2;i<n;i++){
        if(n%i==0){
            return false;
            break;
        }
    }
    return true;
}



//这样时间上可能超时,优化一下(循环i改成i*i)


bool isPrime(int n){
    for(int i=2;i*i<n;i++){
        if(n%i==0){
            return false;
            break;
        }
    }
    return true;
}

 

 F2:while简洁明了,中途退出去

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int x;
	cin>>x;
	int i=2;
	bool b=1;
	while (i*i<=x && b==1)
		if (x%i==0) b=0;
		else i++;
	if (b==1) cout<<"Yes";
	else cout<<"No";
	return 0;
}

F3:无脑算法

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a,i;
	cin>>a;
	for(i=2;i<=a-1;i++)
		if(a%i==0){
		   printf("No");
	       return 0;
        }
	printf("Yes");
	return 0;
}

F4:埃拉托斯特尼(Eratosthenes)筛法

boo isPrime(int target,int[] isprime, int n){
	isprime[2]=0;
    int k=2,tt=0;
    while(tt<n+1){
       for(int i=1; i<isprime.length; i++){ //将不是素数的数筛出
           if(i%k==0&&i!=k) isprime[i]=1;
       }
       for(int i=1; i<isprime.length; i++){ //将筛选后的第一个数当做新的筛子
           if(i>k&&isprime[i]==0){
             k=i;
             break;
           }
       }
       tt++;
    }
	if(isprime[target]==1)return  true;
	else return false;
}

F5:欧拉筛法

void PrimeList(int* Prime, bool* isPrime, int n) {
    int i = 0, j = 0, count = 0;

    if (isPrime != NULL) {//确保isPrime不是空指针
        //将isPrime数组初始化为 1
        for (i = 2; i <= N; i++) {
            isPrime[i] = true;
        }
    }

    if (isPrime != NULL && Prime != NULL) {
        //从2遍历到范围上限N
        for (i = 2; i <= N; i++) {
            if (isPrime[i])//如果下标(下标对应着1 ~ 范围上限N)对应的isPrime值没有被置为false,说明这个数是素数,将下标放入素数数组
                Prime[count++] = i;
            //循环控制表达式的意义:j小于等于素数数组的个数 或 素数数组中的每一个素数与 i 的积小于范围上限N
            for (j = 0; (j < count) && (Prime[j] * (long long)i) <= N; j++)//将i强制转换是因为vs上有warning,要求转换为宽类型防止算术溢出。数据上不产生影响
            {
                isPrime[i * Prime[j]] = false;//每一个素数的 i 倍(i >= 2)都不是素数,置为false

                //这个是欧拉筛法的核心,它可以减少非素数置false的重复率
                //意义是将每一个合数(非素数)拆成 2(最小因数)与最大因数 的乘积
                if (i % Prime[j] == 0)
                    break;
            }
        }
    }
}

质数素数方面,在时间复杂度上是很有要求的,所以要优化简化:如下面一题

T2:筛法求质数

说明

求2-n之间的所有质数。

输入格式

一个正整数n,n<=105。

输出格式

2..n 之间的所有质数,中间以空格隔开。

样例
输入数据 1
10
输出数据 1
2 3 5 7

F1:暴力方法简洁易懂

#include<bits/stdc++.h>
using namespace std;
int n,cnt;//cnt表示质数的数量 
int zs[100005];//prime
bool b[100005];//b[i]表示第i个数有没有被筛掉//b[i]==1 不是质数,b[i]==0 是质数 
int main()
{
	cin>>n;
	for(int i=2;i<=n;i++)
	{
		if(b[i]==0)
		{
			cnt++;
			zs[cnt]=i;
			for(int j=2*i;j<=n;j+=i)
			{
				b[j]=1;
			}
		}
	}
	for(int i=1;i<=cnt;i++)
	{
		cout<<zs[i]<<' ';
	}
	return 0;
}

F2:优化方法简洁快捷

#include<bits/stdc++.h>
using namespace std;
const int mx=100010;
int a[mx];
int i,j,n;
int main()
{
	cin>>n;
	for (i=2; i<=n; i++) a[i]=1;
	for (i=2;i*i<=n;i++) {
	  	if (a[i]==1)
	  	  for (j=2*i;j<=n;j+=i) 
	  	     a[j]=0;
	  	
	}
	for (i=2; i<=n; i++) if (a[i]==1) cout<<i<<' ';
	return 0;
}

F3:普通方法易懂

#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int a[100000];
int main(){
	int n;
	cin>>n;
	int s=0;
	for(int i=2;i<=n;i++){
		if(a[i]==1)
		{
			continue;
		}
		cout<<i<<" ";
		s++;
		for(int j=2;i*j<=n;j++){
			a[i*j]=1;
		}
	}
}

制作不易,点个赞呗!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值