【SeedCoder 2015年热身题1 常规】质数问题(题目+答案)

【问题】

输入一个整数n,输出1-n之内(包括整数n)的所有质数。

【输入】

输入由一系列的整数构成,每一个整数以Tab键隔开,每一个数表示一个n

【输出】

对于每一个n,输出1-n的所有质数,之间以Tab 键隔开。每一个测试样例另起一行。

【示例输入】

5             11          

【示例输出】

2             3             5

2             3             5             7             11


----------------------------------------------------------------------------------------------------------------------------------------------------------------

【解答】

示例代码中采用了两种方法,一种为常规方法,另一种采用埃氏筛选法。具体的介绍可以参考:http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes。你们可以手动修改示例代码中的Methodmethod_temp在不同方法中进行切换,并修改输入n的值(比如:10000000)以比较不同算法之间的运行速率。一般而言当数据量较大时,埃氏筛选法优势明显;数据量较小时区别不大。

下面附上原理图:



【示例代码】


//--------------------------------------【程序说明】-------------------------------------------
//		程序说明:某段连续整数中的所有质数
//		程序描述:
//		IDE版本:Visual Studio 2013
//		作者:Arthur Lee
//------------------------------------------------------------------------------------------------  

//【1】头文件
#include <fstream>
#include <ctime>
#include <cmath>
using namespace std;

#define TIMER
#define MAXNUMBER 10000001
//【2】函数声明
bool IsPrime(int);
void RangeIsPrime(int);
void InitialData(int);
//【3】定义枚举体,在几种方法中切换
enum Method
{
	Normal,
	Eratosthenes//埃氏筛选
};

//【4】变量声明
bool flag[MAXNUMBER];//初始化数组,true表示是质数

int main(){
#ifdef TIMER
	clock_t start = clock();
#endif // TIMER
	ifstream fin("in.txt");
	if (fin.fail())
		return 1;
	ofstream fout("out.txt");

	Method method_temp = Method::Normal;//控制使用的方法
	int test;

	while (!fin.eof())
	{
		fin >> test;
		InitialData(test);//每次检测事例之前,初始化所需的数据
		switch (method_temp)
		{
		case Normal:
			for (int i = 1; i <= test; ++i)
			{
				flag[i] = IsPrime(i);
			}
			break;
		case Eratosthenes:
			RangeIsPrime(test);//将需要判断的n传入函数
			break;
		default:
			break;
		}
		fout << "all primes between 1 and " << test << " are" << "\n";

		int count_temp = 0;
		for (int i = 1; i <= test; ++i)
		{
			if (flag[i])
				fout << i << "\t";
			else
				continue;

			if (++count_temp == 6){//控制输出格式
				count_temp = 0;
				fout << "\n";
			}
		}

	}
#ifdef TIMER
	clock_t end = clock();
	double duration = (double)(end - start);
	fout << "runtime : " << duration << "ms" << endl;
#endif // TIMER
	fout.close();
	return 0;
}


//【5】函数实现
//n为质数时,返回true
bool IsPrime(int n){
	//这里未对n<=0 做判断处理
	if (n == 1)
		return false;

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

void RangeIsPrime(int n){
	for (int i = 2; i <= (int)sqrt(n); ++i){
		if (!flag[i])
			continue;
		
		int j = i + i;
		while (j <= n){
			flag[j] = false;
			j += i;
		}
	}
}

void InitialData(int n){

	for (int i = 0; i <= n; ++i){
		flag[i] = true;
	}
	flag[0] = false;
	flag[1] = false;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值