首先发布在这里。我会切入追逐:为什么这种方法有效?我一直在盯着它看最后一小时试图弄清楚它,但我觉得令我困惑的是,只有很多变数。
任何人都可以帮我解释一下,也许是一行一行吗?假设 is_prime?(i)是先前的方法,用于测试某个数字是否为素数。谢谢!
f
答案 0 :(得分:2)
您的方法is_prime?
可以写成
require 'prime'
def is_prime?(n)
Prime.prime?(n)
end
请参阅文档Prime::is_prime?。
现在让我们添加一些puts
语句来查看您的代码发生了什么。
def nth_prime(n)
prime_num = 0
i = 2
puts "i=#{i}"
while true
puts " is_prime?(#{i})=#{is_prime?(i)}"
if is_prime?(i)
prime_num += 1
puts " prime_num=#{prime_num}"
puts " prime_num==#{n}: #{prime_num==n}"
if prime_num == n
puts "Found #{n}th prime!"
return i
end
end
i += 1
puts "i=#{i}"
end
end
然后
nth_prime(3)
打印以下内容。
i=2
is_prime?(2)=true
prime_num=1
prime_num==3: false
i=3
is_prime?(3)=true
prime_num=2
prime_num==3: false
i=4
is_prime?(4)=false
i=5
is_prime?(5)=true
prime_num=3
prime_num==3: true
Found 3th prime!
#=> 5
如果您单步执行代码并将语句与上述打印结果进行比较,您应该能够理解所执行的操作。如果能回答你的问题,请在评论中告诉我。
以下是您可以收紧代码的方法。
def nth_prime(n)
prime_count = 0
i = 1
until prime_count == n
i += 1
prime_count += 1 if is_prime?(i)
end
i
end
nth_prime(4) #=> 7
以下是一种类似Ruby的方法来处理这个问题。
require 'prime'
def nth_prime(n)
return 2 if n==1
enum = Prime.each
(n-1).times { enum.next }
enum.next
end
请参阅Prime#each和Enumerator#next。
nth_prime(1) #=> 2
nth_prime(2) #=> 3
nth_prime(3) #=> 5
nth_prime(4) #=> 7
nth_prime(10_000) #=> 104729
答案 1 :(得分:2)
重命名一些变量并从current_number == 0
开始,以明确我们逐个查看每个数字。
def nth_prime(n)
prime_count = 0 #keeps track of how many primes we have so far
current_num = 0 #current number
while true
if is_prime?(current_num)
prime_count += 1
if prime_count == n
return current_num
end
end
current_num += 1
end
end
正如我所说,我们正在浏览0
中的所有数字,直到使用 while-loop 和current_num += 1
找到第n个素数。
如果current_num
为素数,则prime_count
上升1,对应于第1个素数等。如果prime_count
也等于n
,我们返回{ {1}}这将是第n个素数。
答案 2 :(得分:0)
好的,让我们分解一下:
这里的基本算法是我们遍历每个大于1的数字,检查每个数字的素数,直到找到第n个素数。变量prime_num
(虽然命名不佳)实际上包含了迄今为止发现的素数的计数。因此,当它等于函数参数n
时,函数将返回相应的素数。变量i
仅用于保存被检查的数字 - 最初,它是2,并且每次经过循环时增加1。因此,当i
的值为素数时,prime_num
的值会增加,当prime_num
达到魔法n
时,i
的值会增加({1}}返回时返回。
它不是一个非常有效的算法,但它能完成这项工作,而且并不是很难理解。然而,正如其他地方所说的那样,建议尽可能使用标准库函数。