《劍指offer》 自己寫乙個pow函式

2021-07-22 05:42:32 字數 2550 閱讀 4440

今天打google在codejam上辦的apactest,成績還行吧(最後排名540),第二題逗比了,自己邏輯後來理清楚,但是**還是原來的想法,wa了兩次才找到了bug。

第二題需要實現乙個整數的pow函式,之前只會遞迴的寫法,今天學會了迭代的寫法,回想《劍指offer》裡也有類似的東西,所以整理成這篇部落格。

比如求2的10次冪,可能有人隨手十幾秒就寫完了:

typedef long

long ll;

ll pow(int

base, int exponent)

return ans;

}

如果exponent是比較大的呢?有沒有更快的?

我們把exponent表示成二進位制的形式,比如15=1111,那麼其實有: a11

=a10112=

a10002+

102+1

2=a10002∗

a102∗

a12=

a8∗a

2∗a1

這樣計算的話,我們只需要計算lo

g2(e

xpon

ent)

次就夠了!對比232

和32,完全不一樣的數量級!

那麼**怎麼寫呢?

typedef long

long ll;

ll pow(int

base, int exponent)

return ans;

}

其實我覺得**已經很清楚了,如果還不清楚的話,可以稍微解釋一下(請先自行熟悉位運算):

假如我們使用上面的函式來迭代計算31

1 ,根據上面所使用的公式,11表示為二進位制是1011,計算過程是這樣的:

第一步:發現1011的最低位為1,ans乘上31

為3,1011右移一位變成101;

第二步:發現101的最低位為1,ans乘以32

變成27,101右移一位變成10;

第三步,發現10的最低位不為1,ans不變,10右移一位變成1;

第四步,發現1的最低位為1,ans乘以38

變成177147,1右移一位變成0,退出while迴圈。

注意每一步裡的31

,32 ,34

,38 是怎麼來的呢?用的就是last_pow(注意初始值)這個量來每次平方自己計算出來的!第三步裡雖然ans不變,但是last_pow還是得平方一下,否則沒法在第四步裡變成所需要的38

。注意現在的問題變成了整數次冪了,也就是包括負數次冪了!

首先回顧一下冪運算的定義: a−

x=1a

x,x為

正整數

a0=1

,a不等

於0也就是說,對於負數次冪,其實只要計算它的絕對值次冪,再用1去除就可以了,還要注意檢查計算0的0次冪這種非法情況!

typedef double numbertype;

// 計算非負整數次冪的函式

numbertype powwithoutnegativeexp(numbertype base, int exponent)

return ans;

}// 浮點數相等的判斷比較特別

bool equald(numbertype numa, numbertype numb)

// 處理各種情況的冪運算的函式

numbertype pow(numbertype base, int exponent)

bool isnegative = false;

if (exponent < 0)

numbertype result = powwithoutnegativeexp(base, exponent);

return isnegative ? 1 / result : result;

}

注釋**裡有了~應該是很清晰的。

另附上完整的使用示例:

#include 

#include

using

namespace

std;

typedef

double numbertype;

numbertype powwithoutnegativeexp(numbertype base, int exponent)

return ans;

}bool equald(numbertype numa, numbertype numb)

numbertype pow(numbertype base, int exponent)

bool isnegative = false;

if (exponent < 0)

numbertype result = powwithoutnegativeexp(base, exponent);

return isnegative ? 1 / result : result;

}int main()

return

0;}

自己寫乙個LIST

pragma once forward declarations templateclass clistnode templateclass clist template class clistnode void insertafter t data template void clistnode ...

自己寫乙個框架

自己寫乙個框架 單入口mvc 類 庫 屬於擴充套件 乙個好的配置檔案和讀取功能 db介面 dispather.php index.php dispather 分析controller action 根據分析controller action 動態載入 引入乙個自動載入機制 controller.ph...

自己寫乙個BaseDao

通過反射可以獲得實體的屬性和類的名字我們就可以拼接處sql語句 查詢的萬能dao public static void select object o 通過物件獲取類物件 class c o.getclass 獲取類中的屬性 field fields c.getdeclaredfields 設定許可...