几种简单的求素数算法的复杂度分析

素数的算法有很多种,现在主要讲两种算法及其改进版本的复杂度分析,解释性能提升的幅度。现以求100000内素数为例,两种算法分别是:
  1.基础思路是去掉偶数,包括取模的范围,代码如下:
   print(2)

     for i in range(3,100000,2):
      for a in range(3,int(i*0.5)+1,2):
       if i%a == 0:
       break
       else:
         print(i,end = ‘ ‘)
此两层循环的算法的复杂度为0.5n((n**0.5+1)/2)

          2.应用一个素数定理:大于6的素数一定与6的倍数相邻,代码如下:
              print(2,3,end = ‘ ‘)

    t = 100000 // 6 + 1
    for i in range(1,t):
     x = 6 * i - 1
    for j in range(3,int(x**0.5)+1,2):
    if x % j == 0:
    break
     else:
      print(x ,end = ‘ ‘)

     y = 6 * i + 1
     for j in range(3, int(y0.5)+1,2):
     if y % j == 0:
     break
    else:
      print(x ,end = ‘ ‘)
此算法的复杂度为(n/3052)(n
0.5+1)/2,将总范围分成30为一块,则6的倍数有5个,相邻的数就是10个。

                     优化思路:
                     对于1号算法,我们知道末尾是5的数一定能被5整除,所以末位是5的数一定不是素数,复杂度可以降为0.4*n*((n**0.5+1)*0.4)。不是偶数且末为不是5,就剩(1,3,7,9),所以4/10=0.4,第二层循环也是如此。优化效率提升56%(0.5**2/0.4**2-1=0.56)。
                     对于2号算法,思路也是刨去末位为5的数。例如,30~60这一块内,6的倍数有(36,42,48,54,60),相邻的数是(35,37,41,43,47,49,53,55,59,61),有两个末位是5的数(35,55),所以将总范围分成30为一块,只需计算8个数,优化后复杂度为(n/30*(5*2-2))*(n**0.5+1)*0.4=4/15*n*(n**0.5+1)*0.4。相比优化后的1号算法,优化后的2号算法效率提升50%(其余项约分,只剩0.4/(4/15),所以0.4/(4/15)-1=0.5)。

                    综上可见,降低算法复杂度是提高解决问题效率的不二法门。

原文地址:http://blog.51cto.com/13886271/2154947

时间: 2024-10-21 05:09:25

几种简单的求素数算法的复杂度分析的相关文章

比较排序算法及复杂度分析

比较排序算法分类 比较排序(Comparison Sort)通过对数组中的元素进行比较来实现排序. 比较排序算法(Comparison Sorts) Category Name Best Average Worst Memory Stability  插入排序  (Insertion Sorts) 插入排序 (Insertion Sort) n n2 n2 1 Stable 希尔排序 (Shell Sort) n n log2 n n log2 n 1 Not Stable  交换排序 (Exc

几种简单的负载均衡算法及其Java代码实现

什么是负载均衡 负载均衡,英文名称为Load Balance,指由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助.通过某种负载分担技术,将外部发送来的请求均匀分配到对称结构中的某一台服务器上,而接收到请求的服务器独立地回应客户的请求.负载均衡能够平均分配客户请求到服务器阵列,借此提供快速获取重要数据,解决大量并发访问服务问题,这种集群技术可以用最少的投资获得接近于大型主机的性能. 负载均衡分为软件负载均衡和硬件负载均衡,前者的代

java求素数算法

求100内的素数: public void a() { for (int i = 2; i <= 100; i++) { int temp = (int) Math.sqrt(i); // 我把那个aqrt单独提出来,这样速度稍微快一点,虽然在100内变化不大,但如果是10000000内的素数呢? if (i <= 3) { System.out.println(i + " is a prime"); } else { for (int j = 2; j <= tem

一种简单的加解密算法

此算法源码最初由 Borland 的 Delphi 语言编写,似乎 Allen Bauer 是原作者,源码如下. const cMulKey = 52845; cAddKey = 11719; cKey = 1234; function Decrypt(const S: String; Key: Word): String; var I: byte; begin SetLength(Result, Length(S)); for I := 1 to Length(S) do begin Resu

补:用布尔常量求素数算法

输入代码: /* *Copyright (c)2014,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:sum123.cpp *作 者:林海云 *完成日期:2014年12月26日 *版 本 号:v2.0 * *问题描述:输入若干个正整数,将其中的素数输出来. *程序输入:个数不确定的正整数 *程序输出:输出数据中的素数 */ #include <iostream> #include <cmath> using namespace std; bo

算法的复杂度分析

这个是每个学习算法都必须掌握的东西.不过感觉又不太好说的清楚. 大概扯一下.就是因为每个计算机的运行的速度都不一定相同.所以需要一个标准来判断一个程序跑的快慢. 比如一个简单的for循环.for(int i = 0; i < n; i++); 这个循环其实循环了n次.可能在不同的机器上跑的时间不同. 但是都一定会跑n次.所以用O(n)来表示这个循环的时间复杂度. 再举一个例子 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++

求幂算法

1.简单递归 最简单的求幂算法是根据xn=x*xn-1,使用递归: def foo(x,n): if n==0: return 1 else: return x*foo(x,n-1) 这样求x的n次方,会进行n-1次乘法运算,n较大时效率很低. 2.高效递归 一种更高效的算法,可以将运算次数降到LogN的级别,由于: xn=xn/2*xn/2 , n为偶数时 xn=x(n-1)/2*x(n-1)/2*x , n为奇数时 def foo(x,n): if n==0: return 1 else:

素数算法的优化之路

一.素数的定义 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数(不包括0)整除的数.因为合数是由若干个质数相乘而得来的,所以,没有质数就没有合数,由此可见质数在数论中有着很重要的地位. 比如:2,3,5,7,9.....都是素数. 二.构造素数算法 写算法之前,先来说说以下这个东西: 对于任意一个合数n,如果它有两个质因子x,y,显然n = x*y, 所以,由不等式性质可得,x <= sqrt(n), 即 x <= n^(1/2). 推广一下,对于任意一个合数,

试探究一种查找素数算法

解题思路:构造链表,使用筛除法 例如:求10以内素数 链表初始化:2 3 4 5 6 7 8 9 10 进行第一轮筛选后:2 3 5 7 9 也就是用2后面的数去除2, 第二轮筛选后:2 3 5 7 也就是用3后面的数去除3, 第三轮筛选后:2 3 5 7 也就是用5后面的数去除5 第四轮筛选后:2 3 5 7 代码: #include <stdio.h> #include <stdlib.h> #define N 1e5 // over this it is so slowly