Python
 Computer >> コンピューター >  >> プログラミング >> Python

PythonでPow(x, n)を実装する方法|ライブラリ関数を使わずにべき乗を計算するアルゴリズム

問題の概要

2つの入力 x と n が与えられたとします。x は -100.0 から 100.0 の範囲に収まる実数、n は32ビット符号付き整数です。ここでの課題は、ライブラリ関数を使用せずに x の n 乗(x^n)を求めることです。

例えば、入力が x = 12.1、n = -2 の場合、出力は 0.00683 となります。

解法のアプローチ:バイナリ累乗法(繰り返し二乗法)

この問題は「バイナリ累乗法(繰り返し二乗法)」と呼ばれる手法で効率的に解けます。指数を2進数として扱い、計算回数を O(log n) まで削減できるのがポイントです。手順は以下の通りです。

  • power に |n|(n の絶対値)を代入し、res を 1.0 で初期化する
  • power が 0 になるまで以下を繰り返す
    • power の最下位ビットが 1 なら、res := res × x とする
    • x := x × x とする(x を2乗して更新)
  • n が負の場合は 1 / res を返す
  • それ以外の場合は res をそのまま返す

仕組みのポイント

各ループで x を2乗しながら、power を右シフト(>>= 1)していくことで、「n を2進数で表したときのビットが立っている位置」に対応する x の累乗だけを掛け合わせることができます。これにより、単純な掛け算の繰り返し(O(n))よりも大幅に高速な計算が可能になります。また、n が負の場合は最後に逆数を取ることで対応します。

Pythonでの実装例

それでは、実際のコードを見て理解を深めましょう。

class Solution(object):
    def myPow(self, x, n):
        power = abs(n)
        res = 1.0
        while power:
            if power & 1:
                res *= x
            x *= x
            power >>= 1
        if n < 0:
            return 1 / res
        return res

ob1 = Solution()
print(ob1.myPow(45, -2))
print(ob1.myPow(21, 3))

入力

45
-2
21
3

出力

0.0004938271604938272
9261.0

まとめ

この実装では、繰り返し二乗法を用いることで、ライブラリ関数に頼らずに x^n を O(log n) の時間計算量で求めています。負の指数にも対応しており、LeetCode の「Pow(x, n)」問題などでも定番の解法です。ビット演算(& 1 による奇数判定、>>= 1 による右シフト)を活用する点が、このアルゴリズムのエレガントなところと言えるでしょう。

  1. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが

  2. PythonでQuine(クワイン)プログラムを書いてみよう

    「Quine(クワイン)」とは、入力を一切受け取らずに、自分自身のソースコードを出力する特殊なプログラムのことです。一見すると不思議な自己言及的な仕組みですが、実装にはいくつかの厳格なルールがあります。最も重要な条件は、プログラム内部からソースコードファイルを読み込んではいけないという点です。つまり、純粋にコード自身の論理だけで自分の内容を再現しなければなりません。 サンプルコード Pythonでは、わずか1行でQuineを実現できます。 a=a=%r;print (a%%a);print (a%a) 実行結果 a=a=%r;print (a%%a);print (a%a) ご覧のとお