0

階乗を計算するプログラムを作成しようとしています。しかし、以下のコードを実行しようとすると、次のエラーが発生します: undefined method `*' for nil:NilClass (NoMethodError)

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

三項演算子の設定が間違っていますか、それとも何か問題がありますか?

助けてくれてありがとう

4

2 に答える 2

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階乗関数」に由来します。そうすれば、しばらく噛むことができます。

あなたのコードは正しくないいくつかのことをしています:

  • a実行前に定義されていないため、 aを でa*x乗算できないため、失敗する運命にあります。nilx
  • uptoは現在の値を としてブロックに渡しますが、常に新しいローカル変数であるためx、 への代入aは失敗しますaaブロックのスコープ外で定義しない限り、静的メモリはありません。
  • 多くの 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
}

わあ!すべての中間値を計算するつもりですか!? メモリを急速に消費しますが、利点はほとんどありません。

于 2013-09-12T18:16:17.270 に答える