简体   繁体   English

如何找到给定输入值以下的所有质数?

[英]How can I find all prime numbers below a given input value?

I have been tasked with finding all the prime numbers in Ruby (without using the prime method)我的任务是在 Ruby 中查找所有质数(不使用质数方法)

Below is my logic, the issue, my code and the output.下面是我的逻辑、问题、我的代码和输出。

My Logic:我的逻辑:

All primes have only 2 distinct divisors.所有素数只有 2 个不同的除数。 Hence if we count the number of divisors a number has and it is greater than 2, then it is not prime (apart from 1, which I havn't dealth with yet)因此,如果我们计算一个数的除数数并且它大于 2,那么它就不是质数(除了 1,我还没有处理过)

Therefore I have made an array, filled it with all the numbers from 1 – 10 (I'll do 1000 later) and am removing all that have more than 2 divisors因此,我制作了一个数组,用 1 – 10 的所有数字填充它(稍后我会做 1000),并删除所有具有 2 个以上除数的数字

The issue:问题:

The code below seems to not be checking 5,7, or 9.下面的代码似乎没有检查 5,7 或 9。

My code (ruby)我的代码(红宝石)

#Create an array that will be your list of prime numbers
primes = [] 
 
#create variables
x = 1
counter = 0
y=1  
 
#fill array with numbers (I'm using 10 rather than 1000 for now)
for x in 1..10 # 1..10 is inclusive in ruby
primes.push(x)  #put x into primes array
end
 
primes.each do |prime_number|  for y in 1..10 do #for each x and each y, do the following
      puts "#{prime_number} , #{y}" #puts is print with a new line
      if prime_number % y == 0   #check if element in array divided by numbers 1-10 is mod 0
        counter +=1   #is so increase counter by 1
        if counter > 2
          primes.delete(prime_number)
          counter = 0   #if counter get's above 2 then number cannot be prime. hence remove it from array
        end
      end
    end
end
 
puts primes  #print out primes to check result
sum_of_primes = primes.inject(:+)  #sum of all primes
puts sum_of_primes #print answer

Here is output:这是输出:

1 , 1
1 , 2
1 , 3
1 , 4
1 , 5
1 , 6
1 , 7
1 , 8
1 , 9
1 , 10
2 , 1
2 , 2
2 , 3
2 , 4
2 , 5
2 , 6
2 , 7
2 , 8
2 , 9
2 , 10
4 , 1
4 , 2
4 , 3
4 , 4
4 , 5
4 , 6
4 , 7
4 , 8
4 , 9
4 , 10
6 , 1
6 , 2
6 , 3
6 , 4
6 , 5
6 , 6
6 , 7
6 , 8
6 , 9
6 , 10
8 , 1
8 , 2
8 , 3
8 , 4
8 , 5
8 , 6
8 , 7
8 , 8
8 , 9
8 , 10
10 , 1
10 , 2
10 , 3
10 , 4
10 , 5
10 , 6
10 , 7
10 , 8
10 , 9
10 , 10
[1, 3, 5, 7, 9]
25 

TL;DR TL; 博士

You can refactor your iterators to avoid explicit loops and counters.您可以重构迭代器以避免显式循环和计数器。 Even though you're still iterating, leveraging core methods can be faster and easier to debug.即使您仍在迭代,利用核心方法也可以更快、更容易地进行调试。

For completeness, I also provide an example using Ruby's Prime module from the standard library.为了完整起见,我还提供了一个使用标准库中 Ruby 的Prime模块的示例。 This is probably the most correct solution, but the use of the module is a solution that largely dodges the iteration question entirely, at least from a pragmatic point of view.这可能是最正确的解决方案,但使用该模块是一种在很大程度上完全避免迭代问题的解决方案,至少从实用的角度来看是这样。

Simplify Using Iterators简化使用迭代器

If your question is for schoolwork, then my answer may not help you learn whatever it is your instructor wants you to learn from the lesson.如果您的问题是关于功课,那么我的回答可能无法帮助您学习您的老师希望您从课程中学到的任何东西。 Other answers may explain why your current code doesn't work as intended;其他答案可能会解释为什么您当前的代码无法按预期工作; I will instead focus on an alternate approaches that leverage more of Ruby's core capabilities.相反,我将专注于利用更多 Ruby 核心功能的替代方法。

Here's one way to find all the positive primes up to a given maximum value:这是一种找到所有正素数直到给定最大值的方法:

# Use a Range object to check each Integer between 2 and
# (int - 1) to see if there's a remainder. If not, the value
# of i is added to the anonymous array returned by #map. The
# int is prime if there are no elements in the array.
def prime? int 
  (2...int).none? { |i| int.modulo(i).zero? }
end

# Iterate from 2 to the maximum value, using #select to
# return the subset of values passed to the block where the
# return value of #prime? is truthy.
#
# NB: 1 isn't prime, which is why we start from 2. Reference:
# <https://en.wikipedia.org/wiki/Prime_number#Primality_of_one>
def find_primes max_value
  2.upto(max_value).select { |i| prime? i }
end

find_primes 10
#=> [2, 3, 5, 7]

There are certainly other ways to do this, but leveraging built-in iterators like Array#none?当然还有其他方法可以做到这一点,但是利用像Array#none这样的内置迭代器 and Array#select while avoiding counters seems like a net win to me.Array#select同时避免计数器对我来说似乎是一个净胜。 Your mileage may vary.你的旅费可能会改变。

Use the Standard Library使用标准库

As a further simplification, you might simply use the Prime module from the Ruby standard library.作为进一步的简化,您可以简单地使用 Ruby 标准库中的Prime模块。 For example, Prime#each returns an enumerable Prime::EratosthenesGenerator .例如, Prime#each返回一个可枚举的Prime::EratosthenesGenerator You can then call Enumerable#to_a to convert the results to an Array.然后,您可以调用Enumerable#to_a将结果转换为数组。 For example:例如:

require 'prime'

def primes max_value
  Prime.each(max_value).to_a
end

primes 10
#=> [2, 3, 5, 7]

Leveraging core and standard library classes is usually faster (and potentially less error-prone) than implementing your own routines, but this may be "a bridge too far" for educational purposes.利用核心和标准库类通常比实现自己的例程更快(并且可能更不容易出错),但这对于教育目的来说可能是“一座桥太远了”。 Nevertheless, I include it here for completeness and to help future visitors.尽管如此,我将其包含在此处是为了完整性并帮助未来的访问者。

The code below seems to not be checking 5,7, or 9下面的代码似乎没有检查 5,7 或 9

That's because you are deleting elements from the array while traversing it.那是因为您在遍历数组时从数组中删除元素。

As a workaround, you can traverse the array in reverse order using reverse_each :作为一种解决方法,您可以使用reverse_each以相反的顺序遍历reverse_each

primes = (2..20).to_a

primes.reverse_each do |prime_number|
  counter = 0
  1.upto(20) do |y|
    if prime_number % y == 0
      counter += 1
      primes.delete(prime_number) if counter > 2
    end
  end
end

primes
#=> [2, 3, 5, 7, 11, 13, 17, 19]

Or you could use delete_if which deletes the current element in-place if the block evaluates to true :或者您可以使用delete_if ,如果块评估为true ,它会就地删除当前元素:

primes = (2..20).to_a

primes.delete_if do |prime_number|
  counter = 0
  (1..20).find do |y|
    counter += 1 if prime_number % y == 0
    counter > 2
  end
end

primes
#=> [2, 3, 5, 7, 11, 13, 17, 19]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何仅通过在“Ruby”中使用循环(即没有任何捷径)找到1到给定数字之间的素数? - How can I find the prime numbers between 1 to the given number, only by using the loop(ie. without any short cuts) in "Ruby"? 如何在Ruby中找到所有小于1000的素数之和? - How to find the sum of all prime numbers less than 1000 in Ruby? Ruby:使用递归查找素数时出现错误 - Ruby: Getting an error when I use recursion to find prime numbers 在数组中找到最接近给定值的数字 - Find closest numbers in array to given value 我如何将一个给定的值除以两个数字? - How would I divide a given value with only two numbers? 如何生成前 n 个素数? - How do I generate the first n prime numbers? 如何有效筛选选定范围的质数? - How do I efficiently sieve through a selected range for prime numbers? *ruby*我如何开发一个 Ruby 程序,该程序根据用户的要求打印斐波那契数列的项数和质数 - *ruby*how can i develop a Ruby program that prints the numbers of terms of Fibonacci series together with prime number as requested by the user 如何从下面的XML内容中获取值? - How can I get the value from the XML content below? 如何测试一个值是否是 Ruby 中的素数? 简单和困难的方式? - How can I test if a value is a prime number in Ruby? Both the easy and the hard way?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM