7

我已经被这个问题困扰了很长时间。我设法做了一个递归阶乘。

def factorial(n):
     if n == 0:
         return 1
     else:
         return n * factorial(n-1)

双阶乘 对于偶数 n,双阶乘是所有小于或等于 n 的偶正整数的乘积。对于奇数 p,双阶乘是所有小于或等于 p 的奇数正整数的乘积。

如果 n 是偶数,那么n!! = n*(n - 2)*(n - 4)*(n - 6)* ... *4*2

如果 p 是奇数,那么p!! = p*(p - 2)*(p - 4)*(p - 6)* ... *3*1

但我不知道做一个双阶乘。有什么帮助吗?

4

10 回答 10

19
from functools import reduce # only in Python 3

reduce(int.__mul__, range(n, 0, -2))
于 2011-01-19T20:15:23.840 回答
4

这与递归调用具有不同结束条件和不同参数的阶乘不一样吗?

def doublefactorial(n):
     if n <= 0:
         return 1
     else:
         return n * doublefactorial(n-2)

如果n是偶数,那么它将在 时停止n == 0。如果n是奇数,那么它将在 时停止n == -1

于 2011-01-19T20:13:18.263 回答
3

这里的问题是双阶乘是为负实数(-1)定义的!!= 1, (-3)!! = -1 (即使是负整数(例如 -2、-4、...)也应该有 +/- inf 的解)所以......在所有负数的解中,有些东西闻起来很糟糕。如果想为实数定义双阶乘,那么这些解决方案是行不通的。解决方案是使用 gamma 函数定义双阶乘。

import scipy.special as sp
from numpy import pi

def dfact(x):
    n = (x + 1.)/2.
    return 2.**n * sp.gamma(n + 0.5)/(pi**(0.5))

有用!:D

于 2016-04-21T20:05:15.193 回答
2

开始Python 3.8,我们可以使用模块中的prod函数math计算迭代中所有元素的乘积,在我们的例子中是range(n, 0, -2)

import math

math.prod(range(n, 0, -2))

请注意,这也处理n = 0结果为 的情况1

于 2019-02-14T20:51:59.603 回答
1

我的递归解决方案版本,在一行中:

dfact = lambda n: (n <= 0) or n * dfact(n-2)

然而,值得注意的是,双阶乘可以用“正常”阶乘表示。对于奇数,

恩!!= (2*k)!/ (2**k * k!)

其中 k = (n+1)/2。对于偶数参数 n=2k,虽然这与对复杂参数的概括不一致,但表达式更简单,

恩!!=(2k)!!= 2 * k * k!。

所有这一切意味着您可以使用标准数学库中的阶乘函数编写代码,这总是很好的:

import math
fact = math.factorial
def dfact(n):
  if n % 2 == 1:
    k = (n+1)/2
    return fact(2*k) / (2**k * fact(k))
  else:
    return 2**k * fact(k)

现在,这段代码对于大的 n 显然不是很有效,但它很有启发性。更重要的是,由于我们现在正在处理标准阶乘,因此在处理非常大的数字时,这是一个非常好的优化起点。您尝试使用对数或伽马函数来获得大数的近似双阶乘。

于 2014-04-23T18:56:15.700 回答
0
def doublefactorial(n):
     if n in (0, 1):
         return 1
     else:
         return n * doublefactorial(n-2)

应该这样做。

于 2011-01-19T20:15:53.593 回答
0

我希望我理解正确,但这会起作用吗

 def factorial(n):
 if n == 0 or n == 1:
     return 1
 else:
     return n * factorial(n-2)
于 2011-01-19T20:16:31.817 回答
0
def doublefactorial(n):
     if n <= 0:
         return 1
     else:
         return n * doublefactorial(n-2)

That should do it. Unless I'm misunderstanding

于 2011-01-19T20:12:55.440 回答
0
def double_fact(number):
    if number==0 or number==1:
        return 1
    else:
        return number*double_fact(number-2)

我认为这应该对你有用。

于 2011-01-19T20:18:35.803 回答
0

reduce(lambda x,y: y*x, range(n,1,-2))

这与简单的迭代版本基本相同:

x = n
for y in range(n-2, 1, -2):
    x*=y

显然你也可以递归地做,但有什么意义呢?这种使用递归实现的示例在使用所有递归语言时都很好,但是对于命令式语言,它总是使像递归这样的简单工具看起来比必要的复杂,而在处理像树这样的基本递归结构时,递归可以成为一个真正的简化器。

于 2011-01-19T20:22:05.987 回答