python素数筛选法浅析


Posted in Python onMarch 19, 2018

原理:

素数,指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数。在加密应用中起重要的位置,比如广为人知的RSA算法中,就是基于大整数的因式分解难题,寻找两个超大的素数然后相乘作为密钥的。一个比较常见的求素数的办法是埃拉托斯特尼筛法(the Sieve of Eratosthenes) ,说简单一点就是画表格,然后删表格,如图所示:

python素数筛选法浅析

从2开始依次往后面数,如果当前数字一个素数,那么就将所有其倍数的数从表中删除或者标记,然后最终得到所有的素数。

有一个优化:

标记2和3的倍数的时候,6被标记了两次。所以从i的平方开始标记,减少很多时间。

比如3的倍数从9开始标记,而不是6,并且每次加6。

除了2以外,所有素数都是奇数。奇数的平方还是奇数,如果再加上奇数就变成了偶数一定不会是素数,所以加偶数(2倍素数)。

预先处理了所有偶数。

注意:1既不是素数也不是合数,这里没有处理1。

#! prime.py 
import time 
 
def primes(n): 
 P = [] 
 f = [] 
 for i in range(n+1): 
  if i > 2 and i%2 == 0: 
   f.append(1) 
  else: 
   f.append(0) 
 
 i = 3 
 while i*i <= n: 
  if f[i] == 0: 
   j = i*i 
   while j <= n: 
    f[j] = 1 
    j += i+i 
  i += 2 
 
 P.append(2) 
 for i in range(3,n,2): 
  if f[i] == 0: 
   P.append(i) 
 
 return P 
 
def isPrime(n): 
 if n > 2 and n%2 == 0: 
  return 0 
 
 i = 3 
 while i*i <= n: 
  if n%i == 0: 
   return 0 
  i += 2 
 
 return 1 
 
def primeCnt(n): 
 cnt = 0 
 for i in range(2,n): 
  if isPrime(i): 
   cnt += 1 
 return cnt 
 
if __name__ == '__main__': 
 start = time.clock() 
 n = 10000000 
 P = primes(n); 
 print("There are %d primes less than %d"%(len(P),n)) 
 #for i in range(10): 
 # print(P[i]) 
 print("Time: %f"%(time.clock()-start)) 
 #for n in range(2,100000): 
 # if isPrime(n): 
 #  print("%d is prime"%n) 
  #print("%d is "%n + ("prime" if isPrime(n) else "not prime")) 
 
 start = time.clock() 
 n = 1000000 
 print("There are %d primes less than %d"%(primeCnt(n),n)) 
 print("Time: %f"%(time.clock()-start)

用素数筛选法求1千万以内的素数用了5.767s,

普通素数判断法求1百万以内的素数用了9.642s,

用C++素数筛选法求1亿以内的素数用了0.948s,

用C++普通素数判断法求1千万以内的素数用了3.965s,

可见解释语言确实比编译语言慢很多。

附C++程序,用了位压缩优化空间

#include <iostream> 
#include <cstdio> 
#include <algorithm> 
using namespace std; 
#define N 100000001 
 
unsigned f[(N>>5)+5]; 
int p[5761456],m; 
void init() 
{ 
  int i,j; 
  for(i=4;i<N;i+=2) 
    f[i>>5]|=1<<(i&0x1F); 
  p[m++]=2; 
  for(i=3;i*i<N;i+=2) 
    if(!(f[i>>5]&(1<<(i&0x1F)))) 
    { 
      p[m++]=i; 
      for(j=i*i;j<N;j+=i+i) 
        f[j>>5]|=1<<(j&0x1F); 
    } 
  for(;i<N;i+=2) 
    if(!(f[i>>5]&(1<<(i&0x1F)))) 
      p[m++]=i; 
} 
int is_prime(int n) 
{ 
  int i; 
  for(i=0;p[i]*p[i]<=n;i++) 
    if(n%p[i]==0) 
      return 0; 
  return 1; 
} 
int isPrime(int n) 
{ 
  if(n>2 && n%2==0) 
    return 0; 
  int i=3; 
  while(i*i<=n) 
  { 
    if(n%i==0) 
      return 0; 
    i+=2; 
  } 
  return 1; 
} 
int main() 
{ 
  int n=0,i; 
  clock_t st=clock(); 
  init(); 
  /*for(i=2;i<10000000;i++) 
    if(isPrime(i)) 
      n++;*/ 
  printf("%d %dms\n",m,clock()-st); 
  /*while(~scanf("%d",&n),n) 
  { 
    i=lower_bound(p,p+m,n+1)-p; 
    printf("%d\n",i); 
  }*/ 
  return 0; 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python回调函数用法实例分析
May 09 Python
python从入门到精通(DAY 1)
Dec 20 Python
Python3 伪装浏览器的方法示例
Nov 23 Python
Python网络爬虫中的同步与异步示例详解
Feb 03 Python
Python打印“菱形”星号代码方法
Feb 05 Python
基于Python中numpy数组的合并实例讲解
Apr 04 Python
Python3多线程基础知识点
Feb 19 Python
python标识符命名规范原理解析
Jan 10 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
在django中实现choices字段获取对应字段值
Jul 12 Python
如何在Anaconda中打开python自带idle
Sep 21 Python
7个关于Python的经典基础案例
Nov 07 Python
python实现堆和索引堆的代码示例
Mar 19 #Python
python实现一个简单的并查集的示例代码
Mar 19 #Python
python使用筛选法计算小于给定数字的所有素数
Mar 19 #Python
python将每个单词按空格分开并保存到文件中
Mar 19 #Python
python将文本分每两行一组并保存到文件
Mar 19 #Python
python: line=f.readlines()消除line中\n的方法
Mar 19 #Python
Python File readlines() 使用方法
Mar 19 #Python
You might like
php去除数组中重复数据
2014/11/18 PHP
PHP编写RESTful接口的方法
2016/02/21 PHP
浅析Laravel5中队列的配置及使用
2016/08/04 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
表格 隔行换色升级版
2009/11/07 Javascript
JavaScript对象的property属性详解
2014/04/01 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
JavaScript forEach()遍历函数使用及介绍
2015/07/08 Javascript
深入解析jQuery中Deferred的deferred.promise()方法
2016/05/03 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
jQuery插件FusionCharts绘制2D环饼图效果示例【附demo源码】
2017/04/10 jQuery
详解webpack打包vue时提取css
2017/05/26 Javascript
vue实现前进刷新后退不刷新效果
2018/01/26 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
2018/06/24 Javascript
JS获取子节点、父节点和兄弟节点的方法实例总结
2018/07/06 Javascript
解决layui表格的表头不滚动的问题
2019/09/04 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
2019/09/16 Javascript
vue 中几种传值方法(3种)
2019/11/12 Javascript
[09:37]2018DOTA2国际邀请赛寻真——不懈追梦的Team Serenity
2018/08/13 DOTA
利用Django模版生成树状结构实例代码
2019/05/19 Python
Python3.6+Django2.0以上 xadmin站点的配置和使用教程图解
2019/06/04 Python
python pandas获取csv指定行 列的操作方法
2019/07/12 Python
python [:3] 实现提取数组中的数
2019/11/27 Python
Python sublime安装及配置过程详解
2020/06/29 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
"引用"与指针的区别是什么
2016/09/07 面试题
中文系学生自荐信范文
2013/11/13 职场文书
怎样写好创业计划书的内容
2014/02/06 职场文书
购房意向书范本
2014/04/01 职场文书
毕业生评语大全
2015/01/04 职场文书
独生子女证明范本
2015/06/19 职场文书
2016春节放假通知范文
2015/08/18 职场文书
2016大学军训心得体会
2016/01/11 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python