素数算法的不同等级

题目:求小于等于自然数N(N>=2)内的所有素数。

 

等级一:

	int nFlag = 10000;
	int nCount = 0;
	for(int i = 2; i<=nFlag; i++)
	{		
		bool bSS = true;		
		for(int j = 2; j<i; j++)
		{
			if(i%j == 0)
			{
				bSS = false;
				break;
			}
		}
		if(bSS)
		{
//			cout<<i<<'\t';
			nCount++;
		}
	}

N=10000,运行时间是21 ms

等级二:

优化:所有偶数中,只有2是素数

int nFlag = 10000;

	int nCount = 1;
	for(int i = 3; i<=nFlag; i+=2)
	{		
		bool bSS = true;		
		for(int j = 3; j<i; j+=2)
		{
			if(i%j == 0)
			{
				bSS = false;
				break;
			}
		}
		if(bSS)
		{
//			cout<<i<<'\t';
			nCount++;
		}
	}

N=10000,运行时间是10 ms

等级三:

优化:公约数都是成对出现的,所以只要小于sqrt(i)里没有整除的数即可。

	int nFlag = 10000;

	int nCount = 1;
	for(int i = 3; i<=nFlag; i+=2)
	{		
		bool bSS = true;
		float fSqrt = sqrt((float)i);
		for(int j = 3; j<=fSqrt; j+=2)
		{
			if(i%j == 0)
			{
				bSS = false;
				break;
			}
		}
		if(bSS)
		{
//			cout<<i<<'\t';
			nCount++;
		}
	}

N=10000,结果是:1229 运行时间是0.33 ms

等级四:

优化:只需要确保不能整除小于sqrt(i)的所有素数即可。

int nFlag = 10000;
	vector<int> vctInt;

	vctInt.push_back(2);
	for(int i = 3; i<=nFlag; i+=2)
	{		
		bool bSS = true;
		float fSqrt = sqrt((float)i);
		for(int j = 0; vctInt[j]<=fSqrt; j++)
		{
			if(i%vctInt[j] == 0)
			{
				bSS = false;
				break;
			}
		}
		if(bSS)
		{
//			cout<<i<<'\t';
			vctInt.push_back(i);
		}
	}

N=10000,结果是:1229 运行时间是0.28 ms  (这里应该在vector的管理上花费了不少时间)

N=100000000,结果是:5761455  运行时间是25.7  s

等级五:

优化:用内存标记存储素数.

int nSet = 100000000;
	byte *bFlag = new byte[nSet+1];
	memset(bFlag, 0, sizeof(byte)*nSet);
	bFlag[0] = bFlag[1] = 1;
	int nCout = 1;
	int nSqrt = (int)sqrt((float)nSet);

	for(int j = 2; j<=nSet; j+=2)
	{	
		bFlag[j] = 1;
	}
	for(int i = 3; i<=nSet; i+=2)
	{
		if(!bFlag[i])
		{
			int nStart = i;			
			if(i<=nSqrt)
				nStart *= i;
			nCout++;
			for(int j = nStart; j<=nSet; j += 2*i)
			{
				if(!bFlag[j])
					bFlag[j] = 1;
			}
		}		
	}	
	delete []bFlag;

N=100000000,结果是:5761455  运行时间是2458 ms

等级六:

优化:从小到大,每找到一个新的素数s,只需将s*h(s*h<N)的标记置为1即可。(h为大于等于s的所有标记尚且为0的数)

int nSet = 100000000;
	byte *bFlag = new byte[nSet+1];
	memset(bFlag, 0, sizeof(byte)*nSet);
	bFlag[0] = bFlag[1] = bFlag[2] = 1;
	int nCout = 1;
	int nSqrt = (int)sqrt((float)nSet);

	for(int j = 2; j<=nSet; j+=2)
	{	
		bFlag[j] = 1;
	}
	for(int i = 3; i<=nSet; i+=2)
	{
		if(!bFlag[i])
		{			
			nCout++;			
			if(i <= nSqrt+1)
			{	
				for(int j = nSet/i%2 ? nSet/i: nSet/i-1; j>=i; j -= 2)
				{				
					if(bFlag[j] == 0)
						bFlag[i*j] = 1;
				}
			}			
		}		
	}
	cout<<"Count Num:"<<nCout<<endl;
	delete []bFlag;

N=100000000,结果是:5761455  运行时间是1172ms


PS:表达不是很清楚,而且个人感觉这个算法还没有到极限,希望高人能指导一下,给出更好的算法。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值