Python Eratosthenes集实现混乱的筛选

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

我想在序言中首先说明我是一名python新手,我很感激任何能向我的朋友清楚完整地解释这一点的人

我正在查看下面链接中的代码:

我刚刚开始理解迭代器、生成器和yield命令,但我不理解set实现的代码是如何工作的

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
值,其中1i,那么我们就已经在筛子中过滤掉了。我们将范围终止于
n+1
因为这是筛子结束的地方(1弥补了结束界限不包括在内的事实)。当然,我们的间隔被设置为
i
,以产生它的倍数


关于O(log(n))的位指的是在普通集合实现中测试集合成员资格的时间复杂度,而不是完整算法。整个算法的复杂度不能小于O(n),因为外部循环运行
n
-1次(从2到n)。实际上,集合成员资格测试需要O(1)时间,因为Python集是散列表。或者,您可以使用
n
bool
s的
列表,这将以空间为代价获得更好的性能。

Python
set
查找是
O(1)
,而不是
O(log n)
;它基于散列,而不是二叉树或任何东西。实际上,由于碰撞链接,它通常比一次检查多一点,但它没有以一种有意义的方式与
集的大小联系起来。我想我在上一句话中谈到了这一点,我遗漏了什么吗?那一段的第一句话暗示了期望ed时间将是
O(logn)
。错误在Rosetta这边;很抱歉造成混淆。同意,Rosetta夸大了集合查找的成本(平均),一个更好的消息来源是:非常感谢!我感谢你花时间帮助我理解谢谢你Gregor。我感谢你花时间告诉我这件事,下次我遇到问题时一定要记住这一点