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 に答える
1

再帰的ソリューションの私のバージョンを 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!.

これはすべて、標準の数学ライブラリの factorial 関数を使用してコードを記述できることを意味します。これは常に優れています。

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 <= 0:
         return 1
     else:
         return n * doublefactorial(n-2)

それはそれをする必要があります。誤解しない限り

于 2011-01-19T20:12:55.440 に答える
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 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 に答える