在while循环和嵌套if之后出现意外的$ end

时间:2013-05-02 18:43:35

标签: ruby

我有这个我正在研究的程序应该找到前1000个素数的总和。目前我所关心的是确保程序找到前1000个素数,我将添加稍后添加它们的功能。这就是我所拥有的:

#!/usr/bin/ruby

def prime(num)

    is_prime = true

    for i in 2..Math.sqrt(num)

        if (num % i) == 0           
            is_prime = false
        else
            is_prime = true
        end
    end

    return is_prime
end


i = 2
number_of_primes = 0

while number_of_primes < 1000

    prime = prime(i)

    if prime == true
        number_of_primes++

    end
    i++
end

当我尝试运行该程序时,我得到以下反馈:

sumOfPrimes.rb:32: syntax error, unexpected keyword_end
sumOfPrimes.rb:34: syntax error, unexpected keyword_end

是什么给出的?任何方向表示赞赏。

2 个答案:

答案 0 :(得分:10)

Ruby没有++运算符,您需要执行+= 1

number_of_primes += 1

答案 1 :(得分:1)

如果您有兴趣,可以提供一些建议:

关于Ruby的一个很酷的事情是问号在方法名称中是合法的。因此,您经常会发现'谓词'方法(测试某些东西并返回真或假的方法)以问号结尾,如下所示:odd?。您的prime方法是完美的候选方法,因此我们可以将其重命名为prime?

你使用一个局部变量is_prime来确定你是否找到了你正在测试的数字因子 - 这是你期望用命令式语言做的事情,比如java或C - 但Ruby具有函数式编程的各种很酷的功能,你将通过学习获得强大的力量和表现力。如果您以前没有遇到它们,您可能需要谷歌block是什么以及语法如何工作,但为此您可以将其视为在每个项目上运行某些代码的方法一个集合。它可以与各种很酷的方法一起使用,其中一个非常适合您的目的:none?,如果调用它的集合中没有项目,则返回true,当传递给您给出的代码块时,返回true。因此,您的prime?方法可以像这样重写:

def prime? num
  (2..Math.sqrt(num)).none? { |x| num % x == 0 }
end

除了缩短之外,不需要使用像is_prime这样的局部变量的优点是你给自己带来错误的机会更少 - 例如你认为is_prime的内容是一回事但它实际上是另一个。如果仔细观察,它也会更接近质数的实际数学定义。因此,通过删除不必要的代码,您可以更接近地揭示您正在编写的内容的“含义”。

就获得前1000个素数而言,无限流是一种非常酷的方式来做到这一点,但在这里解释可能有点复杂 - 如果你感兴趣,肯定谷歌,因为他们真的很棒!但只是出于兴趣,这是一个简单的方法,你可以使用只是递归和没有局部变量(记住局部变量是魔鬼!):

def first_n_primes(i = 2, primes = [], n)
  if primes.count == n then primes
  elsif prime? i then first_n_primes(i + 1, primes + [i], n)
  else first_n_primes(i + 1, primes, n)
  end
end

就总结它们而言,我要说的是搜索名为inject的红宝石方法 - 也称为reduce。如果您之前没有遇到过这个概念,那么最初可能会有点大脑弯曲但是值得学习!很酷很强大。

玩得开心!