素数问题

判断素数和给出一定范围内素数的方式

素数的定义 只有1和它本身两个因子

判断原理

一个数如果是合数,n = ab;

那么a,b中必然有一个因子是小于等于根号n,如果不存在小等于根号n的因子,那么这个数就是素数


朴素的求N以内素数,O(n*sqrt(n)) 


筛法:

1.筛法为什么成立?

因为从前往后推,比它小的数都不是它的因数,那么它必然是一个素数

2.为什么筛到根号n就可以了?

(为什么大于根号n的合数已经被根号n前面的素数排除了?)

假设一个大于根号n的合数没有被筛掉,那么这个数有两个因子ab,其中一个必然小于等于根号n,那么这个因子要么是合数,要么是质数,都被筛了



10^9 以内的素数文件在GB级别

10^5 素数和逗号保存的txt内在39kb左右


    
1.开一个大的bool型数组prime[],大小就是n+1就可以了.先把所有的下标为奇数的标为true,下标为偶数的标为false.

    2.然后:

#include<iostream>
using namespace std;
const long long int size = 100001;
int prime[size];
int cnt = 0;
int main(int argc, char const *argv[])
{
	prime[2] = 1;
	for(long long i = 3 ; i < size ; i+=2 ) prime[i] = 1;
	for(int i = 3 ; i*i <= size ; i += 2){
		if(prime[i]) for(int j = 2*i ; j < size ; j += i ) prime[j] = 0;
	}
	for(int j = 2 ; j < size ; j++){
		if(prime[j])
		cout<<j<<",";
	}
	//cout<<cnt<<endl;
	return 0;
}


注意的地方:  

(1.开始把所有奇数位置设置成true

(2.要注意筛到根号n就可以了



3.优化筛法

prime只保存奇数的状态

有些prime被访问了两遍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值