素数算法的优化之路

素数算法的优化之路素数算法的优化之路

大家好,又见面了,我是你们的朋友全栈君。一、素数的定义


        质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数(不包括0)整除的数。因为合数是由若干个质数相乘而得来的,所以,没有质数就没有合数,由此可见质数在数论中有着很重要的地位。


        比如:2,3,5,7,9…..都是素数。


 


二、构造素数算法


     写算法之前,先来说说以下这个东西:
     
     对于任意一个合数n,如果它有两个质因子x,y,显然n = x*y, 
     所以,由不等式性质可得,x <= sqrt(n), 即 x <= n^(1/2)。
     
     推广一下,对于任意一个合数,如果它有k个质因子x1,x2,x3,…. ,xk,显然n = x1 * x2 * x3 * …. * xk,
     所以,由不等式性质可得, x <= n^(1/k),即每个质因子必小于或者等于n开k次方,其中x 属于集合{ 

x1,x2,x3,…. ,xk 
}。

    定义一个全局变量和一个全局数组,要是数组是分配在栈上的话,是有容量限制的,所以我们就定义个全局的。

     const unsigned int N = 50000;
     bool flag[N+1];


 

  
  1、算法一:按照定义,即可快速写出一个简单的构造素数算法
 


    

void PrimeCreateCommon()//按照定义
{
	for ( unsigned int i = 2; i <= N; ++i )
	{
		//由前面的铺垫,这里不难理解吧。因为我不知道这个数有几个质因子,
		//我就假设它只有两个,范围拉大一些,这个数的所有质因子都小于或
		//等于sqrt( (double)i ) + 1。其它的约数,必然是这些质因子的倍数
		//而已所以就没必要继续除下去了。
		bool flag = true;
		for ( unsigned int j = 2; j <= sqrt((double)i)+1; ++j )  
		{                              
			if ( i % j == 0 )         
			{                        
				flag = false;
			}
		}
		//if ( flag )
		//{
		// 	cout << i << " "; 
		//}
	}
	cout << endl;
}




   分析:该算法的时间复杂度为O(n*sqrt(n) ),在n比较大时(比如n = 50000),我的机器跑了个二十来秒,就也叫算法,呵呵,所以接下来我们来看另一种算法 ,那就是
古希腊数学家的埃拉托色尼给出的一个比较省力的算法——埃拉托色尼筛法。
 




   2、算法二:筛选法

 


    首先,列出从2开始的数。然后,将2记在素数列表上,再划去所有2的倍数。根据定义,剩下的最小的数——在这里是3——必定是素数。将这个数记在素数列表上,再划去所有它的倍数,这样又会剩下一些数,取其中最小的,如此反复操作。最后剩下的都是素数。
   

void PrimeCreateExt()//筛选法优化
{
	memset( flag, 0, (N+1)*sizeof(bool) );
	for ( unsigned int i = 2; i <= sqrt(double(N)) + 1; ++i )
	{
		if ( !flag[i] )
		{
			for ( unsigned int j = 2*i; j <= N; j += i )
			{
				flag[j] = true;
			}
		}

	}

// 	for ( int i = 2; i <= N; ++i )
// 	{
// 		if ( !flag[i] )
// 		{
// 			cout << i << " ";
// 		}
// 	}
// 	cout << endl;
} 


 三、两种算法的运行时间对比
    
  

//测试函数
int main()
{
	clock_t start, finish;
	double duration = 0.0;

	cout << "筛选算法产生素数:" << endl;
	start = clock();
	PrimeCreateExt();
	finish = clock();
	duration = (double)(finish-start);
	cout << "时间消耗:" << duration << "ms" << endl << endl;

	cout << "普通算法产生素数:" << endl; 
	start = clock();
	PrimeCreateCommon();
	finish = clock();
	duration = (double)(finish-start);
	cout << "时间消耗:" << duration << "ms" << endl << endl; 
} 

   

 //产生50万以内的素数运行时间对比 

素数算法的优化之路

 四、空间上的优化
            略


作者:山丘儿
转载请标明出处,谢谢。原文地址:http://blog.csdn.net/s634772208/article/details/46327281

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151674.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • supergo任我行纵行指南针TT硕点YY考勤打卡定位下载及安装教程

    supergo任我行纵行指南针TT硕点YY考勤打卡定位下载及安装教程**supergo指南针TT硕点YY定位下载及安装教程**supergo指南针TT硕点YY定位下载及安装教程(2021最新版更新)本文以supergo为例,演示说明下载过程1、首先登录supergo下载官网2、2.找到supergo下载的按钮。并点击下载,输入提示密码3.然后选择右上角三个点,选择在safari浏览器中打开。点击下载,安装。弹框请选择安装按钮4.点击设置-通用,描述文件和设备管理,找到证书名称,然后点击信任,即可…

    2022年6月25日
  • 面向新手的Web服务器搭建(一)——IIS的搭建[通俗易懂]

    面向新手的Web服务器搭建(一)——IIS的搭建[通俗易懂]很多童鞋说自己是做移动开发的,想挂个简单的WebAPI,可是服务器又不会搭,这样一来测试就成了问题。看看网上的教程,发现略难懂,而且大多是一个转一个,没价值,所以干脆写几篇文章讲讲简单的Web服务器怎么搭,让不太涉及Web的童鞋快速上手。

    2022年5月8日
  • kafka和flume区别

    kafka和flume区别Flume更趋向于消息采集系统,Kafka更趋向于消息缓存系统。 kafka:目前项目中主要是用来做消息推送中间件,消息的处理完全由业务方自己定义,请求频次单机吞吐量轻轻松松50W+/s,数据在集群不全挂的情况下是不会丢数据,消费也很灵活,可以指定分区和offset,可以当做成一个数据库。 flume:用来做数据采集和落地,目前使用的是flume-ng,流程是source(kafka)->channel->hdfs相比较kafka比较轻量级,就是一个数据的流通管道,当..

    2022年6月23日
  • java和javase一样吗

    java和javase一样吗接口概述:接口是Java语言中的一种引用类型,是方法的”集合”,所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK7及以前),额外增加默认方法和静态方法(JDK8),额外增加私有方法(jdk9)。接口的定义,它与定义类方式相似,但是使用interface关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。publicclass类名.java–>.classpublicinterface接口名.java–>.class接口的使

    2022年7月7日
  • JQuery EasyUI window 用法

    JQuery EasyUI window 用法JQuery代码 var$win;$win=$(‘#test-window’).window({title:’添加课程设置信息’,width:820,height:450,top:($(window).height()-820)*0.5,left:($(window).width()-450)*0.5,…

    2022年7月18日
  • laravel怎么开启调试模式

    laravel怎么开启调试模式

    2021年10月20日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号