语法错误? Ruby bug?实例变量增加+ = 1的问题?

时间:2013-12-23 23:00:55

标签: ruby

def isPrime?(num)

    i = 2

    @isFalse = 0

    while i < num
        divisible = ((num % i) == 0)
        if divisible
            @isFalse += 1
            return false
        end
        i += 1
    end
    true
end

def primes(max)
    startTime = Time.now
        (2..max).each do |p|
            puts "#{p} #{isPrime?(p)}"
        end
    endTime = Time.now

    puts "--------------------------------------------------"
    puts "   FALSE values in range from (2 thru #{max}): #{@isFalse}  \n    TRUE values in range from (2 thru #{max}): #{max-1-@isFalse}"
    puts "\nTotal time to calculate is #{endTime - startTime} seconds!"
end

primes(10)

isPrime?检查给定数字是否为素数。 primes加载一系列数字并检查每个数字是否为素数。

我想知道在该范围内有多少数字是素数,有多少数字不是。

我添加@isFalse += 1认为每次返回false都可以递增,这样我就可以确定该范围内有多少个数字是假的,并使用它从max减去得到多少个数是真的

@isFalse未正确递增外,整个代码工作正常。这是为什么?谢谢你的帮助。

- UPDATE -
我的输出:在puts "About to increment @isFalse"

之前添加了@isFalse += 1
2 true
3 true
About to increment @isFalse
4 false
5 true
About to increment @isFalse
6 false
7 true
About to increment @isFalse
8 false
About to increment @isFalse
9 false
About to increment @isFalse
10 false
--------------------------------------------------
   FALSE values in range from (2 thru 10): 1  
    TRUE values in range from (2 thru 10): 8

4 个答案:

答案 0 :(得分:2)

每次调用isPrime?时,@isFalse都会重置为0.因此@isFalse为1的结果来自上一次调用isPrime?num 1}}等于10,将@isFalse递增到1)。

答案 1 :(得分:1)

您似乎正在尝试使用@isFalse找出该范围内的素数。如果是这种情况,您应该使用以下代码修改(尽管我不建议以这种方式检查质数,并且代码效率非常低):

基本上,我完全删除了实例变量@isFalse,并在第二种方法中检查了数字是否为素数。这样的代码更加清晰,并且真正做到了你打算做的事情。

您的代码存在的问题是,每次调用第一个方法@isFalse时,0都会重置为isPrime?,因此无法正确反映此处的素数数量给定范围。

def isPrime?(num)
    i = 2
    while i < num
        divisible = ((num % i) == 0)
        return false if divisible
        i += 1
    end
    true
end

def primes(max)
    startTime = Time.now
        is_prime = 0
        (2..max).each do |p|
            if isPrime?(p)
                is_prime += 1
                puts p
        end
    endTime = Time.now

    puts "--------------------------------------------------"
    puts "   FALSE values in range from (2 thru #{max}): #{is_prime}  \n    TRUE values in range from (2 thru #{max}): #{max-1-is_prime}"
    puts "\nTotal time to calculate is #{endTime - startTime} seconds!"
end

primes(10)

答案 2 :(得分:1)

当你的问题得到解答时,我想建议一个类似Ruby的解决方案:

您希望方法is_prime?除了确定num是否为素数之外什么都不做:

def is_prime?(num)
  (2...num).each {|i| return false if num % i == 0}
  true
end

在方法nbr_primes中计算素数。

def nbr_primes(max)
  return false if max < 2
  (2..max).reduce(0) {|tot, i| tot + (is_prime?(i) ? 1 : 0)}
end

p nbr_primes(20) # => 8

几点:

  • 我删除了对时间和输出格式的引用,因为它们不是问题的核心。
  • 使用小写字母和下划线命名方法是一种Ruby约定。
  • (2...num),因为它有三个点,是从2到(和包括)num - 1的序列。我们可以改为写(2..num-1)(两个点),这是一些人青睐的。
  • (2..max).reduce(0) {|tot, i|...}从{2}遍历i并包括maxtotreduce的累加器,对于发现为素数的2和max之间的每个数字递增1。表达式返回tot的值,而nbr_primes又由方法inject返回。 reducen的同义词。
  • 在检查数字Math.sqrt(n).to_i是否为素数时,您只需检查它是否可被require 'prime'之前的数字整除。
  • 使用Prime.prime?(7) #=> true,您无需重新发明轮子。例如,Prime.take_while {|p| p <= 10}.size #=> [2, 3, 5, 7].size + 1 # => 4和{{1}}。

答案 3 :(得分:0)

@isFalse = 0位于您的isPrime?方法中。把它拿出来!