我快疯了:阶乘的 Ruby 函数在哪里?不,我不需要教程实现,我只想要库中的函数。它不在数学中!
我开始怀疑,它是标准库函数吗?
标准库中没有阶乘函数。
像这样更好
(1..n).inject(:*) || 1
它不在标准库中,但您可以扩展 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 迭代阶乘是更好的选择。
无耻地抄袭http://rosettacode.org/wiki/Factorial#Ruby,我个人最喜欢的是
class Integer
def fact
(1..self).reduce(:*) || 1
end
end
>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
此实现也恰好是 Rosetta Code 中列出的变体中最快的。
添加|| 1
以处理零情况。
感谢和感谢Mark Thomas,这里有一个更高效、优雅和晦涩的版本:
class Integer
def fact
(2..self).reduce(1,:*)
end
end
在数学中,factorial of n
只是gamma function of n+1
(见:http ://en.wikipedia.org/wiki/Gamma_function )
如果需要, RubyMath.gamma()
只需使用Math.gamma(n+1)
并将其转换回整数即可。
您还可以使用Math.gamma
归结为整数参数的阶乘函数。
class Integer
def !
(1..self).inject(:*)
end
end
!3 # => 6
!4 # => 24
我会做
(1..n).inject(1, :*)
我只是写了我自己的:
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
def factorial(n=0)
(1..n).inject(:*)
end
factorial(3)
factorial(11)
向所有参与并花时间帮助我们的人致以崇高的敬意,我想分享我对此处列出的解决方案的基准。参数:
迭代 = 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)
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.
只是另一种方法,尽管它确实没有必要。
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
您可能会发现 Ruby功能请求很有用。它包含一个包含演示 Bash 脚本的重要补丁。简单循环与批处理中提供的解决方案之间的速度差异实际上可以达到 100 倍(百倍)。全部用纯 Ruby 编写。
这是我的版本,即使它不那么干净,我似乎也很清楚。
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
当有一个用于这个确切目的的内置迭代器时,为什么标准库需要一个阶乘方法?它被称为upto
。
不,您不需要使用递归,就像所有其他答案一样。
def fact(n)
n == 0 ? 1 : n * fact(n - 1)
end
相反,内置迭代器 upto 可用于计算阶乘:
factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
=> 3628800
还有另一种方式(=
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)
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
在 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)
还有一种方法:
# fact(n) => Computes the Factorial of "n" = n!
def fact(n) (1..n).inject(1) {|r,i| r*i }end
fact(6) => 720