为什么这个三元运算符不起作用(Ruby)?

时间:2013-09-12 17:55:42

标签: ruby ternary-operator

我正在尝试编写计算阶乘的程序。但是,当我尝试运行下面的代码时,我收到此错误:nil的未定义方法`*':NilClass(NoMethodError)

1.upto(number) {|x| a = x==1 ? 1 : a*x }

我是否错误地设置了三元运算符,或者是其他错误?

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

您的三元运算符设置正确,但您的变量a未在您进行乘法的位置定义。

这将有效,因为b有一个值:

b = 5

1.upto(number) {|x| a = x==1 ? 1 : b*x }

答案 1 :(得分:2)

我会这样做:

def factorial(number)
  (2 .. number).inject(1) { |m, n| m * n }
end

factorial(1) # => 1
factorial(2) # => 2
factorial(3) # => 6
factorial(5) # => 120
对于像这样的事情,

inject是一种有用的方法,并且不限于与数字一起使用。

可以写得更简洁:

(1..n).inject(:*) || 1

来自“Ruby factorial function”。那会给你一些东西可以咀嚼一段时间。

您的代码正在做一些不正确的事情:

  • a在运行之前从未定义过,因此a*x注定会失败,因为您无法将nil乘以x
  • upto会将当前值作为x传递到块中,但分配给a将失败,因为它始终是新的局部变量a。除非您在块的范围之外定义它,否则没有a的静态内存。
  • 在很多Ruby迭代器中,块的值可以用作返回值。 upto不起作用。您将获得返回的种子值,因此,您将返回1

使用Ruby附带的IRB最好解决这些问题。在交互式会话中,您可以尝试使用代码的变体来查看哪些有效。它比尝试编写脚本并完成编辑/运行周期更快,更容易,更方便。


  

这个怎么样:

factorial = Hash.new{ |x,y| x[y]= y<2 ? 1 : x[y-1]*y }

让我们通过放入IRB来测试它,看看它的作用:

>> factorial = Hash.new{ |x,y| x[y]= y<2 ? 1 : x[y-1]*y }
{}
>> factorial[1]
1
>> factorial
{
    1 => 1
}
>> factorial[2]
2
>> factorial
{
    1 => 1,
    2 => 2
}
>> factorial[100]
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
>> factorial
{
      1 => 1,
      2 => 2,
      3 => 6,
      4 => 24,
      5 => 120,
      6 => 720,
      7 => 5040,
      8 => 40320,
      9 => 362880,
     10 => 3628800,
    ...
    100 => 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
}

YOW!你要计算每个中间值!?它将迅速消耗内存,而且几乎没有优势。