计算一定范围内素数个数的算法

问题概述

问题:给定一个大整数N,计算开区间(1,N)的素数有多少?

  • 算法1:根据素数性质,a不能整除小于等于根号a的所有整数,则必为素数,从1到N遍历找出所有素数。
  • 算法2:素数筛选法,先剔除2的倍数,再剔除剩余的数中第一个数的倍数,直到剩余的数中第一个数大于根号N,此时剩下的数必全部为素数。

算法实现

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>

#undef  TRUE
#define TRUE    1
#undef  FALSE
#define FALSE   0

typedef int BOOL32;

// a不能整除小于等于根号a的所有整数,则必为素数
void ChoosePrimeNumber_Slow(int dwTestSize)
{
	BOOL32* pbNumber = new BOOL32[dwTestSize];
	if (NULL == pbNumber)
	{
		printf("[ChoosePrimeNumber_Slow] New Error!\n");
		return;
	}
	memset(pbNumber, 0, dwTestSize*sizeof(int));

	int dwIndex, dwLoop = 0;
	*(pbNumber+2) = TRUE;
	for(dwIndex=3; dwIndex<dwTestSize; dwIndex++)
	{ 
		for(dwLoop=2; dwLoop<= dwIndex; dwLoop++)
		{
			if(dwIndex%dwLoop==0) 
				break;

			if (dwLoop > (int)sqrt((double)dwIndex))
			{
				*(pbNumber+dwIndex) = TRUE;
				break;
			}
		}
	}	
	// 计算素数个数
	int dwNum = 0;
	for(dwIndex=2; dwIndex<dwTestSize; dwIndex++) 
	{
		if(*(pbNumber+dwIndex))
			dwNum++;
	}
	printf("less than %d, there are %d prime number!\n", dwTestSize, dwNum);

	delete []pbNumber;
	return;
}

// 素数筛选法
void ChoosePrimeNumber_Fast(int dwTestSize)
{
	BOOL32* pbNumber = new BOOL32[dwTestSize];
//	BOOL32* pbNumber = (BOOL32*) malloc(sizeof(BOOL32)*dwTestSize);
	if (NULL == pbNumber)
	{
		printf("[ChoosePrimeNumber_Fast] New Error\n");
		return;
	}	
	memset(pbNumber, 0, dwTestSize*sizeof(int));

	int dwIndex, dwLoop = 0;
	*(pbNumber+2) = TRUE;
	for(dwIndex=3; dwIndex<dwTestSize; dwIndex++)
	{
		if(0 != dwIndex%2) 
			*(pbNumber+dwIndex)=TRUE;
		else
			*(pbNumber+dwIndex)=FALSE;
	}
		
	for(dwIndex=3; dwIndex<=(int)sqrt((double)dwTestSize); dwIndex++)
	{
		if(*(pbNumber + dwIndex))
		{
			for(dwLoop=dwIndex+dwIndex; dwLoop<dwTestSize; dwLoop+=dwIndex) 
				*(pbNumber+dwLoop)=FALSE;
		}
	}
	// 计算素数个数
	int dwNum = 0;
	for(dwIndex=2; dwIndex<dwTestSize; dwIndex++)
	{
		if( *(pbNumber+dwIndex))
			dwNum++;
	}	
	printf("less than %d, there are %d prime number!\n", dwTestSize, dwNum);

	delete []pbNumber;
//	free(pbNumber);
	return;
}

///
int main()
{
	clock_t cBegin, cTime = 0;

	int dwTestNum = 10000;
	for (int dwloop = 0; dwloop<5; dwloop++)
	{
		cBegin = clock();
		ChoosePrimeNumber_Slow(dwTestNum);
		cTime = clock() - cBegin;

#ifndef  WIN32
		cTime=cTime/1000;
#endif
		printf("[%d] Method ChoosePrimeNumber_Slow spend %d ms.\n\n", dwloop, cTime);
		
		cBegin = clock();
		ChoosePrimeNumber_Fast(dwTestNum);
		cTime = clock() - cBegin;
		
#ifndef  WIN32
		cTime=cTime/1000;
#endif
		printf("[%d] Method ChoosePrimeNumber_Fast spend %d ms.\n\n", dwloop, cTime);

		dwTestNum = dwTestNum*10;
	}

	return 0;
}

运行结果

  • CPU:Intel Core i3 2120
  • RAM:2G
less than 10000, there are 1229 prime number!
[0] Method ChoosePrimeNumber_Slow spend 2 ms.

less than 10000, there are 1229 prime number!
[0] Method ChoosePrimeNumber_Fast spend 0 ms.

less than 100000, there are 9592 prime number!
[1] Method ChoosePrimeNumber_Slow spend 41 ms.

less than 100000, there are 9592 prime number!
[1] Method ChoosePrimeNumber_Fast spend 1 ms.

less than 1000000, there are 78498 prime number!
[2] Method ChoosePrimeNumber_Slow spend 973 ms.

less than 1000000, there are 78498 prime number!
[2] Method ChoosePrimeNumber_Fast spend 32 ms.

less than 10000000, there are 664579 prime number!
[3] Method ChoosePrimeNumber_Slow spend 23846 ms.

less than 10000000, there are 664579 prime number!
[3] Method ChoosePrimeNumber_Fast spend 398 ms.

less than 100000000, there are 5761455 prime number!
[4] Method ChoosePrimeNumber_Slow spend 643918 ms.

less than 100000000, there are 5761455 prime number!
[4] Method ChoosePrimeNumber_Fast spend 4695 ms.

Press any key to continue

算法分析

从运行结果显而易见,算法2效率要远远高于算法1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值