Python Eratosthenes集实现混乱的筛选
我想在序言中首先说明我是一名python新手,我很感激任何能向我的朋友清楚完整地解释这一点的人 我正在查看下面链接中的代码: 我刚刚开始理解迭代器、生成器和yield命令,但我不理解set实现的代码是如何工作的Python Eratosthenes集实现混乱的筛选,python,sieve-of-eratosthenes,Python,Sieve Of Eratosthenes,我想在序言中首先说明我是一名python新手,我很感激任何能向我的朋友清楚完整地解释这一点的人 我正在查看下面链接中的代码: 我刚刚开始理解迭代器、生成器和yield命令,但我不理解set实现的代码是如何工作的 def eratosthenes2(n): multiples = set() for i in range(2, n+1): if i not in multiples: yield i multiple
def eratosthenes2(n):
multiples = set()
for i in range(2, n+1):
if i not in multiples:
yield i
multiples.update(range(i*i, n+1, i))
我很难理解这个函数的最后一行是做什么的
另外,有人能给我解释一下为什么这个实现是O(log(n))时间吗?最后一行:
multiples.update(range(i*i, n+1, i))
将从i
的平方到n
的i
的所有倍数添加到集合倍数
。i
平方以下的任何倍数都将在先前的i
集合中
Rosetta没有说算法是O(log(n)),当然不是,但只是集合查找是O(log(n))与列表O(n)。原因是集合使用散列作为查找的手段,实际上是O(1)与O(n)表达式范围(i,j,k)
以k
的间隔生成一个从i
到j
的整数列表(j
是非包容性的,因此包容性边界是j-1
)(默认为1)。因此范围(2,10,2)
生成列表[2,4,6,8]
最后一行所做的是将i
的所有倍数从i
2插入到n
集合倍数
。我们从i
2开始,因为i
是一个素数(因为在筛选中找不到它),而i
的次最小倍数不在multiples
中是i
×i
。证明:如果i
的次最小倍数等于某些c的c×i
值,其中1n+1
因为这是筛子结束的地方(1弥补了结束界限不包括在内的事实)。当然,我们的间隔被设置为i
,以产生它的倍数
关于O(log(n))的位指的是在普通集合实现中测试集合成员资格的时间复杂度,而不是完整算法。整个算法的复杂度不能小于O(n),因为外部循环运行
n
-1次(从2到n)。实际上,集合成员资格测试需要O(1)时间,因为Python集是散列表。或者,您可以使用n
bool
s的列表,这将以空间为代价获得更好的性能。Pythonset
查找是O(1)
,而不是O(log n)
;它基于散列,而不是二叉树或任何东西。实际上,由于碰撞链接,它通常比一次检查多一点,但它没有以一种有意义的方式与集的大小联系起来。我想我在上一句话中谈到了这一点,我遗漏了什么吗?那一段的第一句话暗示了期望ed时间将是O(logn)
。错误在Rosetta这边;很抱歉造成混淆。同意,Rosetta夸大了集合查找的成本(平均),一个更好的消息来源是:非常感谢!我感谢你花时间帮助我理解谢谢你Gregor。我感谢你花时间告诉我这件事,下次我遇到问题时一定要记住这一点