我试图在Ruby 2.1中实现this "find the nth prime number" algorithm。
我也将它标记为“算法”,因为我认为这个问题与语言无关,并且即使您不熟悉,编写的Ruby代码也很容易阅读。我使用了描述性变量名来帮助它。
听起来很简单。所以我写了我的方法(函数):
def nth_prime(n)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
primes[-1].upto(Float::INFINITY) do |p|
return primes[n-1] if primes.length >= n-1
possible_prime = true
primes_to_check = primes.select{|x|x<=Math.sqrt(p)}
primes_to_check.each do |f|
if f%p==0
possible_prime = false
break
end
end
primes << p if possible_prime
end
end
目的是说nth_prime(10)
并获得第10个素数。
解释我的逻辑:
我从已知素数列表开始,因为算法需要。我列出了前十名。
然后我遍历整个数字系统。 (primes[-1]+2).upto(Float::Infinity) do |p|
将提供从最后一个已知素数加上两个(因为+1将导致偶数和均数超过2不能为素数)的每个数字到无穷大的缩进块p
。我没有跳过偶数并且
如果已知素数列表已经至少 n 元素长,我做的第一件事就是返回 n 质数。这适用于已知值 - 如果你要求第5个,那么你将得到11个结果。
然后我将标记possible_prime
设置为true
。这表明没有任何东西证明它不是一个素数。我将进行一些测试,如果它没有将标志更改为false
,那么p
被证明是素数并被附加到已知质数数组。最终该数组将与 n 一样长并返回第n个值。
我创建了一个数组primes_to_check
,其中包含所有已知的素数&lt; = p的平方根。每个人依次以f
进行测试。
如果f可以干净地划分p ,我知道p不是素数,所以我将标志更改为false
和break
,这将我们带出了质数检查循环并返回到无限循环。在该循环中只剩下一个语句,如果标志为真,则附加到known-primes数组的语句,不是这样,我们用下一个数字重新启动循环。
如果没有f
s可以干净地划分p 那么p必须是素数,这意味着它可以存活到素数到检查循环的末尾,并且标志仍然设置为true ,并达到最终'附加p到已知素数'的声明。
最终,这将使primes
数组足够长,以回答“什么是第n个素数?”这个问题。
要求获得第10个素数确实得到了29,这是我预先提供的最后一个素数。但要求11获得nil
,或没有价值。我已经对代码进行了一百次,并且无法想象没有返回值的情况。
我做错了什么?
答案 0 :(得分:1)
return primes[n-1] if primes.length >= n-1
要让primes
拥有索引为n-1
的元素,其长度必须至少为n
。
if f%p==0
检查候选人是否可以分割已知素数,而不是候选人是否可被已知素数整除。
primes[-1].upto(Float::INFINITY) do |p|
这将在列表中已经存在的素数处开始循环(29)。正确地发现29是素数,因此它再次被添加到列表中。您希望在29之后以数字开始循环。
答案 1 :(得分:0)
Algorithm for testing prime no.s:
1)Input num
2)counter= n-1
3)repeat
4)remainder = num%counter
5)if rem=0 then
6)broadcast not a prime.no and stop
7)change counter by -1
8)until counter = 1
9)say its a prime and stop