1

我有一个我正在研究的程序,它应该找到前 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

是什么赋予了?任何方向表示赞赏。

4

2 回答 2

11

Ruby没有++运算符,你需要做+= 1

number_of_primes += 1
于 2013-05-02T18:48:19.923 回答
1

不请自来,但如果您有兴趣,请提供一些建议:

Ruby 最酷的事情之一是问号在方法名称中是合法的。因此,您经常会发现“谓词”方法(测试某些内容并返回真或假的方法)以问号结尾,如下所示odd?:你的prime方法是一个完美的候选者,所以我们可以重命名它prime?

你使用一个局部变量 ,is_prime来保存你是否找到了你正在测试的数字的一个因子——这是你希望在诸如 java 或 C 之类的命令式语言中做的事情——但是 Ruby 拥有所有函数式编程中的各种很酷的功能,您将通过学习获得强大的功能和表现力。如果您以前没有遇到过它们,您可能需要在 Google 上搜索 ablock是什么以及语法是如何工作的,但为此,您可以将其视为一种在集合的每个项目上运行一些代码的方法。它可以与各种很酷的方法一起使用,其中一个非常适合您的目的: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

至于总结它们,我要说的是搜索一个名为的 ruby​​ 方法inject- 也称为reduce. 如果您之前没有遇到过这个概念,一开始可能会有点脑筋急转弯,但它非常值得学习!非常酷而且非常强大。

玩得开心!

于 2013-05-02T20:58:14.390 回答