Pythonで階乗を計算する – 反復計算と再帰計算

定義によれば、階乗とはある正の整数と、その数以下のすべての正の整数の積のことである。

つまり、ある数の階乗を求めるということは、その数から1までのすべての整数を掛け合わせるということである。

0!は慣例的に1にも等しい。

階乗は、整数の後にエクスクラメーションマークを付けて表します。

5!は5の階乗を表します。

そして、その階乗を計算するために、その数字とそれより小さい整数を1まで掛け合わせるのです。

5! = 5 * 4 * 3 * 2 * 1
5! = 120


これらのルールを念頭に置きながら、このチュートリアルでは、Pythonでループと再帰を使って、整数の階乗を計算する方法を学びます。

まず、ループを使った階乗の計算から始めましょう。

ループを使った階乗の計算

階乗の計算は while ループと for ループの両方を使って行うことができる。

一般的な処理はどちらもよく似ている。

必要なのは、入力としてのパラメータとカウンタだけです。

まずは、forループから始めましょう。

def get_factorial_for_loop(n):
    result = 1
    if n > 1:
        for i in range(1, n+1):
            result = result * i
        return result
    else:
        return 'n has to be positive'


お気づきかもしれませんが、階乗の定義は与えられた数から1まででしたが、ここでは1からn`まで数えています。

1*2*3*4…*n=n*(n-1)*(n-2)*(n-3)*(n-4)…*(n-(n-1))1*2*3*4…*n=n*(n-1)*(n-2)*(n-3)*(n-4) …*(n-(n-1))
1 * 2 * 3 * 4 … * Ÿ n = n Ÿ (n-1) Ÿ (n-2) Ÿ (n-3) Ÿ (n-4) … * ♪♪♪~

(n-(n-1))`は常に1になります。

つまり、どの方向から数えてもいいということです。

1から始まってnに向かって増加することも、nから始まって1に向かって減少することもできます。

この関数はパラメータとして、階乗を計算する数を表す n を受け取ります。

まず、 result という名前の変数を定義して、その値として 1 を代入します。

なぜ0でなく1を代入するのか?

なぜなら、もし0を代入してしまうと、それ以降の0との掛け算は当然ながら全て巨大な0になってしまうからです。

そして、forループを1からn+1までの範囲で開始します。

Pythonの範囲は第2引数の前で停止することを忘れないでください。

最後の数字も含めるには、単純に 1 を追加します。

forループの中では、現在のresultの値と、現在のインデックスi` を掛け合わせます。

最後に、最終的な result の値を返します。

それでは、この関数をテストして結果を表示してみましょう。

inp = input("Enter a number: ")
inp = int(inp)


print(f"The result is: {get_factorial_for_loop(inp)}")


ユーザーの入力を得る方法についてもっと知りたい方は、 Python でユーザーの入力を得る を参照してください。

をご覧ください。

ユーザーに入力を促すプロンプトが表示されます。

ここでは 4 で試してみます。

Enter a number: 4
The result is: 24


計算機で結果を確認することができます。

4 は 4 * 3 * 2 * 1 で、結果は 24 です。

それでは、whileループを使ってどのように階乗を計算するか見てみましょう。

以下は、私たちが修正した関数です。

def get_factorial_while_loop(n):
    result = 1
    while n > 1:
        result = result * n
        n -= 1
    return result


これは、forループとよく似ています。

ただし、今回は n から 1 に向かって移動しており、数学的な定義に近くなっています。

では、この関数をテストしてみましょう。

inp = input("Enter a number: ")
inp = int(inp)


print(f"The result is: {get_factorial_while_loop(inp)}")


入力としてもう一度4を入力しよう。

コード偽

計算結果は「4 * 3 * 2 * 1」ですが、最終的な結果は前と同じです。

ループを使った階乗の計算は簡単でしたね。

次に、再帰的関数を使った階乗の計算を見てみましょう。

再帰を用いた階乗の計算

再帰関数とは、自分自身を呼び出す関数のことです。

最初は少し難しく感じるかもしれませんが、我慢してください、再帰関数は簡単に理解できることがわかります。

一般的に、すべての再帰的関数は、ベースケースと再帰的ステップの2つの主要なコンポーネントを持っています。

ベースケースは、問題の最小のインスタンスである。

また、ブレーク、つまり値を返して再帰から抜け出すケースもある。

階乗関数で言えば、階乗の最終要素である1を返す場合がベースケースとなる。

ベースケースがない場合や、ベースケースが正しくない場合は、再帰関数が無限に実行され、オーバーフローを起こす可能性があります。

再帰的ステップとは、その名の通り、関数の再帰的な部分で、問題全体をより小さなものに変換するものです。

再帰的なステップが問題を縮小するために失敗した場合、再び再帰は無限に実行することができます。

階乗の再帰的な部分を考えてみよう。

  • 5!は、5 * 4 * 3 * 2 * 1`である。

しかし、我々は次のことも知っている。

  • 4 * 3 * 2 * 1` は 4!である。

つまり、5!は「5 * 4!」であり、4!は「4 * 3!」である、というように。

ということは、n! = n * (n-1)! となります。

これが階乗の再帰的なステップになります。

となります。

階乗の再帰は、1になった時点で終了します。

これは私たちの基本的なケースになります。

n1以下の場合は1` を返し、入力が 0 の場合をカバーします。

それでは、再帰的階乗関数を見てみましょう。

Enter a number: 4
The result is: 24


ifブロックが基本ケースを表し、else` ブロックが再帰的ステップを表しているのがわかると思います。

それでは、この関数をテストしてみましょう。

def get_factorial_recursively(n):
    if n <= 1:
        return 1
    else:
        return n * get_factorial_recursively(n-1)


今回は入力として 3 を入力する。

inp = input("Enter a number: ")
inp = int(inp)


print(f"The result is: {get_factorial_recursively(inp)}")


同じ結果が得られます。

でも、今回はちょっと面白いことが行われています。

入力があると、この関数は if ブロックでチェックし、3 が 1 よりも大きいので else ブロックにスキップします。

このブロックの中で、 return n * get_factorial_recursively(n-1) という行があります。

とりあえず現在の n の値は 3 であることが分かっていますが、 get_factorial_recursively(n-1) はまだ計算中です。

次に、プログラムは同じ関数をもう一度呼び出しますが、今度は私たちの関数が2をパラメータとして受け取ります。

ifブロックをチェックし、elseブロックまでスキップして、再び最後の行に遭遇します。

ここで、現在のnの値は2ですが、プログラムはまだget_factorial_recursively(n-1)` を計算する必要があります。

そこで、もう一度関数を呼び出しますが、今度は if ブロックというか、ベースクラスが 1 を返すことに成功して、再帰から抜け出します。

上と同じパターンで、各関数の結果を返し、現在の結果に前の n を掛けて、前の関数呼び出しの結果を返します。

つまり、このプログラムは、まず階乗の底(1)に到達し、その後、各ステップで乗算しながら、上へ上へと積み上げていくのである。

また、最終的に n * (n-1) の結果が返されるまで、関数を1つずつコールスタックから取り除いていきます。

これが、一般的な再帰的関数の動作です。

より複雑な問題では、複数の基本ケースや複数の再帰的ステップを持つ、より深い再帰が必要になるかもしれない。

しかし、今のところ、この単純な再帰は階乗問題を解くのに十分なものです。

Pythonの再帰についてもっと知りたい方は、「Pythonで再帰を理解するためのガイド」をご覧ください! &gt.
をご覧ください。

結論

今回は、「for」と「while」ループを使った階乗の計算方法について説明しました。

また、再帰とは何か、再帰を使った階乗の計算方法についても学びました。

もし、再帰を楽しんで、もっと練習したいのであれば、再帰を使ってフィボナッチ数列を計算してみてください。

また、私たちの記事について何か質問や感想があれば、コメント欄で気軽にシェアしてください。

タイトルとURLをコピーしました