电影里的代码之《机械姬》:筛法求质数

来源:Keybord_dancer

今天看了《机械姬》,探讨人工智能话题的电影,豆瓣评分7.5,还是蛮不错的一部电影。影片1:09:29处出现了一段python代码,细看了一下,发现是筛法求质数的python代码,写得非常简练的。先贴个电影的截图:

影片里的代码略微有点模糊,我重新打一遍,是下面这个样子的

#coding:utf8
import sys

def sieve(n):
    #compute primes using sieve eratosthenes
    x = [1] * n
    x[1] = 0

    for i in range(2,n/2):
        j = 2 * i
        while j < n:
            x[j] = 0
            j = j + i
    return x

def prime(n,x):
    #Find nth prime
    i = 1
    j = 1
    while j <= n:
        if x[i] == 1:
            j = j + 1
        i = i + 1
    return i-1

x = sieve(10000)

code = [1206,301,384,5]
key = [1,1,2,2]

sys.stdout.write("".join(chr(i) for i in [73,83,66,78,32,61,22]))

for i in range(0,4):
    sys.stdout.write(str(prime(code[i],x)-key[i]))

代码的最后打印出来下面这个很奇怪的东西,目测是一本书的ISBN,上豆瓣查了一下,是Embodiment and the Inner Life,是关于思维、意识的内容的,和本片的主题息息相关。

ISBN =9780199226559[Finished in 0.1s]

重点还是前面的两个函数实现的筛法求质数。首先介绍一下什么是筛法,筛法相传是古希腊的埃拉托斯特尼发明的一种检测素数的算法。筛法的思路非常简单,可以用下面的动图来描述。给定一个范围,首先用2去筛,把所有2的倍数都筛掉,然后再用3筛,用5筛,不断重复下去......


再来看代码

def sieve(n):             //对n以内的数进行筛选,返回一个长度为n的布尔数组
    #compute primes using sieve eratosthenes
    x = [1] * n         //定义长度为n的布尔数组(实际上电影里用1和0来表示true和false了)
    x[1] = 0            //1既不是素数也不是合数,设为0

    for i in range(2,n/2)://i从2开始一直到n/2
        j = 2 * i    //j从2倍i开始
        while j < n:
            x[j] = 0  //把所有i的倍数筛除
            j = j + i //下一个i的倍数
    return x          //返回数组

def prime(n,x):   //求第n个素数,只需要在筛选好的布尔数组中找第n个标记为1的数就可以了
    #Find nth prime
    i = 1    //初始化为1
    j = 1
    while j <= n:   //在布尔数组中寻找第n个标记为1的数
        if x[i] == 1:
            j = j + 1
        i = i + 1
    return i-1    //前面循环中i多加了一次,返回时需要减1

可以看到,使用筛法求第n个质数的时间复杂度为O(nlog(n)),缺点在需要提前求得筛选的结果,增加了空间复杂度,筛选结果可以用比特位来表示以节省空间。

此外还有一个问题,在求第n个质数的时候,如何要确定第n个质数的大致范围,以确定筛选结果的布尔数组长度。根据素数定理,可以用来估算某个范围内的素数个数,可以用公式x/ln(x)来描述,ln表示自然对数,假设要估计10000以内有多少质数,代入公式10000/ln(10000)得到的结果为1085.73,使用上面的筛法得到的10000以为的质数个数为1229,可以看到估计值比实际值略小一点,估计的范围越大,估计值与实际值的误差越小。实际使用中可以通过公式计算估计值,然后按一定百分比扩大范围即可。

今年第六届大会PyConChina2016,由PyChina.org发起,CPyUG/TopGeek 等社区协办,将在2016年9月10日(上海)9月25日(深圳)10月15日(北京、杭州)地举办的针对Python开发者所举办的最盛大和权威的Python相关技术会议,由PyChina社区主办,致力于推动各类Python相关的技术在互联网、企业应用等领域的研发和应用。

您可以点击此处
了解更多详情,或者扫描下图二维码:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容