92

我快疯了:阶乘的 Ruby 函数在哪里?不,我不需要教程实现,我只想要库中的函数。它不在数学中!

我开始怀疑,它是标准库函数吗?

4

20 回答 20

140

标准库中没有阶乘函数。

于 2010-03-12T17:23:20.487 回答
116

像这样更好

(1..n).inject(:*) || 1
于 2012-09-13T21:57:18.480 回答
77

它不在标准库中,但您可以扩展 Integer 类。

class Integer
  def factorial_recursive
    self <= 1 ? 1 : self * (self - 1).factorial
  end
  def factorial_iterative
    f = 1; for i in 1..self; f *= i; end; f
  end
  alias :factorial :factorial_iterative
end

由于明显的性能原因,NB 迭代阶乘是更好的选择。

于 2010-03-12T17:23:37.477 回答
29

无耻地抄袭http://rosettacode.org/wiki/Factorial#Ruby,我个人最喜欢的是

class Integer
  def fact
    (1..self).reduce(:*) || 1
  end
end

>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

此实现也恰好是 Rosetta Code 中列出的变体中最快的。

更新#1

添加|| 1以处理零情况。

更新#2

感谢和感谢Mark Thomas,这里有一个更高效、优雅和晦涩的版本:

class Integer
  def fact
    (2..self).reduce(1,:*)
  end
end
于 2012-05-11T17:56:15.770 回答
16

在数学中,factorial of n只是gamma function of n+1
(见:http ://en.wikipedia.org/wiki/Gamma_function )

如果需要, RubyMath.gamma()只需使用Math.gamma(n+1)并将其转换回整数即可。

于 2016-05-20T17:37:18.507 回答
14

您还可以使用Math.gamma归结为整数参数的阶乘函数。

于 2012-01-02T11:54:42.777 回答
13
class Integer
  def !
    (1..self).inject(:*)
  end
end

例子

!3  # => 6
!4  # => 24
于 2016-02-18T17:23:56.617 回答
9

我会做

(1..n).inject(1, :*)
于 2014-04-27T16:24:36.063 回答
6

我只是写了我自己的:

def fact(n)
  if n<= 1
    1
  else
    n * fact( n - 1 )
  end
end

此外,您可以定义下降阶乘:

def fall_fact(n,k)
  if k <= 0
    1
  else
    n*fall_fact(n - 1, k - 1)
  end
end
于 2012-03-14T06:54:46.307 回答
4

只需调用此函数

def factorial(n=0)
  (1..n).inject(:*)
end

例子

factorial(3)
factorial(11)
于 2015-11-03T00:46:28.913 回答
4

向所有参与并花时间帮助我们的人致以崇高的敬意,我想分享我对此处列出的解决方案的基准。参数:

迭代 = 1000

n = 6

                                     user     system      total        real
Math.gamma(n+1)                   0.000383   0.000106   0.000489 (  0.000487)
(1..n).inject(:*) || 1            0.003986   0.000000   0.003986 (  0.003987)
(1..n).reduce(1, :*)              0.003926   0.000000   0.003926 (  0.004023)
1.upto(n) {|x| factorial *= x }   0.003748   0.011734   0.015482 (  0.022795)

对于 n = 10

  user     system      total        real
0.000378   0.000102   0.000480 (  0.000477)
0.004469   0.000007   0.004476 (  0.004491)
0.004532   0.000024   0.004556 (  0.005119)
0.027720   0.011211   0.038931 (  0.058309)
于 2019-04-18T08:52:56.950 回答
3

Using Math.gamma.floor is an easy way to produce an approximation and then round it back down to the correct integer result. Should work for all Integers, include an input check if necessary.

于 2014-01-10T18:00:46.397 回答
1

只是另一种方法,尽管它确实没有必要。

class Factorial
   attr_reader :num
   def initialize(num)
      @num = num
   end

   def find_factorial
      (1..num).inject(:*) || 1
   end
end

number = Factorial.new(8).find_factorial
puts number
于 2014-07-06T20:54:28.157 回答
1

您可能会发现 Ruby功能请求很有用。它包含一个包含演示 Bash 脚本的重要补丁。简单循环与批处理中提供的解决方案之间的速度差异实际上可以达到 100 倍(百倍)。全部用纯 Ruby 编写。

于 2014-12-16T02:56:51.950 回答
1

这是我的版本,即使它不那么干净,我似乎也很清楚。

def factorial(num)
    step = 0
    (num - 1).times do (step += 1 ;num *= step) end
    return num
end

这是我的 irb 测试线,显示了每个步骤。

num = 8;step = 0;(num - 1).times do (step += 1 ;num *= step; puts num) end;num
于 2016-01-05T19:44:18.707 回答
1

当有一个用于这个确切目的的内置迭代器时,为什么标准库需要一个阶乘方法?它被称为upto

不,您不需要使用递归,就像所有其他答案一样。

def fact(n)
  n == 0 ? 1 : n * fact(n - 1)
end  

相反,内置迭代器 upto 可用于计算阶乘:

factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
 => 3628800
于 2019-03-22T15:20:25.547 回答
0

还有另一种方式(=

def factorial(number)
  number = number.to_i
  number_range = (number).downto(1).to_a
  factorial = number_range.inject(:*)
  puts "The factorial of #{number} is #{factorial}"
end
factorial(#number)
于 2014-11-24T01:44:25.497 回答
0
class Integer
  def factorial
    return self < 0 ? false : self==0 ? 1 : self.downto(1).inject(:*)
    #Not sure what other libraries say, but my understanding is that factorial of 
    #anything less than 0 does not exist.
  end
end
于 2013-05-12T23:57:26.900 回答
0

在 Ruby标准库中,阶乘函数不可用。我们可以通过这种方式在 ruby​​ 中制作一个简单的阶乘函数。

def factorial_number(n)
 if n <= 1
    1
 else
    n * factorial_number(n-1)
  end
end

puts factorial_number(6) #Output is 720   => (6*5*4*3*2*1)
puts factorial_number(8) #Output is 40320 => (8*7*6*5*4*3*2*1)
于 2021-11-17T10:33:01.123 回答
0

还有一种方法:

# fact(n) => Computes the Factorial of "n" = n!

def fact(n) (1..n).inject(1) {|r,i| r*i }end

fact(6) => 720
于 2017-08-26T15:19:14.987 回答