Algorithm 我怎样才能用埃拉托什尼筛得到第n个素数?

Algorithm 我怎样才能用埃拉托什尼筛得到第n个素数?,algorithm,math,Algorithm,Math,我已经编写了一个函数,sieve(n),它使用Eratosthenes的sieve来返回一个所有素数的数组,最大值为n sieve(25) # ==> [2, 3, 5, 7, 11, 13, 17, 19, 23] 可以读取此函数的源代码 我现在想重构它,以便sieve(n)将返回nth素数。我只是不知道该怎么做。我不想编写一个全新的更复杂的函数,所以最好的方法似乎是计算出筛子的计数值 例如,如果我要第27个素数,筛的初始整数列表应该是2到(我知道第27个素数不大于)。但是有没有一个简

我已经编写了一个函数,
sieve(n)
,它使用Eratosthenes的sieve来返回一个所有素数的数组,最大值为
n

sieve(25) # ==> [2, 3, 5, 7, 11, 13, 17, 19, 23]
可以读取此函数的源代码

我现在想重构它,以便
sieve(n)
将返回
n
th素数。我只是不知道该怎么做。我不想编写一个全新的更复杂的函数,所以最好的方法似乎是计算出筛子的计数值

例如,如果我要第27个素数,筛的初始整数列表应该是2到(我知道第27个素数不大于)。但是有没有一个简单的方法来计算出这个值是多少呢

我研究了这个问题,发现第n个素数必须介于
n*Math.log(n)+n*(Math.log(Math.log(n))-1
n*Math.log(n)+n*Math.log(Math.log(n))
(其中
Math.log
是自然对数的红宝石),但是,简单地在这两个数字之间设置一个数字数组,会使筛选结果产生奇怪的值,比如第15个素数的值(56不是素数,答案应该是47)


你可以猜到,我完全不适合这里。如果有人能给我一些建议,我将非常感激。

埃拉托什尼的筛子总是要从头开始;你不能在任意的时间间隔内进行筛选,因为你会失去所有较小的素数。所以你不必关心下限,只关心上限。你给出的,并且证实了:

n的pn 所以简单地接受这个界限,插入你的n,迭代直到你找到n个素数。你的筛子通常会有点太大,但如果界限相当紧,就不会太大,我希望是这样

有关该边界的表格或绘图,请参见。顺便说一下,创建表的代码也在做同样的事情。我想要至少500个条目,所以我计算了一下

n=500
lst=列表(范围(2,ceil)(n*log(n*log(nщщ)'))
ps=[]
而lst:
p=lst[0]#下一个素数
私人秘书长(p)
lst=[i为lst中的i,如果i%p!=0]

从中得到了500多个素数,然后我可以向您展示计算的界与实际值的比较。

您不应该要求它在任何值之间生成素数。整个算法是建立在这样一个知识的基础上的:在继续之前,它已经找到了某一点之前的所有素数。你需要让它找到从1到上限的素数。下面的方法是可以接受的解决方案吗?使用您在问题中提到的上界(但我不知道,也不知道为什么它是正确的)生成所有小于上界的素数,并返回列表的第n个元素。@Codor这是我认为可行的,但它有一些我不理解的非常奇怪的结果。如果我将初始列表设置为2的上界,我会得到一段时间的素数,然后只是一个稳定的计数——267268269270271等等。这很奇怪。与其在这些边界之间列出素数,不如使用筛选函数来计算小于上界的素数,然后计数到所需的素数。如果你得到了非素数,那么你的筛选函数是不正确的。@GreenTriangle这不是我的意思;我的意思是保留Erathosthenes筛的原样,但使用上界作为参数(即生成从零到界的所有素数),然后从Erathosthenes筛的结果返回所需的条目。如果您在代码中看到
%
;它不是埃拉托什尼的筛子。这里是a@J.F.Sebastian是的,我很懒。当然,更符合纸笔版算法的精神的是有一个布尔列表,并逐步迭代。但是,只有不被划掉的数字可以更容易地找到下一个素数,避免了一行代码和两级缩进。当然,在一定的计算成本下。基于模的算法与筛选算法无关,例如,前者具有不同(更糟糕)的时间复杂度。