快速冪算法的原理及實現

冪運算,即次方運算,例如計算 10^{8}的值即是冪運算,在實現的時候我們往往是這樣寫的:

int __pow(int a,int b){
    int ans = 1;
    while(b--){
        ans *= a;
    }
    return ans;
}

其中a是底數,b爲指數。從時間複雜度上分析這個算法的複雜度是O(n)級別,咋一看好像好很快,但是往往在比賽、做題的時候都需要處理指數很大運算,例如 10^{10^{6}},即是 10^{1000000},這個時候如果用上面的算法來計算的話,就要循環一百萬次,程序就會超時。這個時候快速冪算法就呼之欲出了,先放代碼實現:

int __poww(int a,int b){
    int ans = 1;
    while(b){
        if(b & 1 != 0){
            ans *= a;
        }
        a *= a;
        b >>= 1;
    }
    return ans;
}

快速冪算法的原理是通過將指數拆分成幾個因數相乘的形式,來簡化冪運算。在我們計算 3^{13}的時候,普通的冪運算算法需要計算13次,但是如果我們將它拆分成 3^{8+4+1},再進一步拆分成 3^{8} *3^{4}*3^{1} 只需要計算4次。嗯?哪來的4次?,別急,接着看。

這種拆分思想其實就是借鑑了二進制與十進制轉換的算法思想,我們知道13的二進制是1101,可以知道:13= 1*2^{3}+1*2^{2}+0*2^{1}+1*2^{0} = 8+4+1

實現的代碼已經給出,原理就是利用位運算裏的位移“>>”和按位與“&”運算,代碼中 b & 1其實就是取b二進制的最低位,用來判斷最低位是0還是1,再根據是0還是1決定乘不乘,不理解的話聯繫一下二進制轉換的過程。b >>= 1其實就是將b的二進制向右移動一位,就這樣位移、取最低位、位移、取最低位,這樣循環計算,直到指數b爲0爲止,整個過程和我們手動將二進制轉換成十進制是非常相似的。普通冪算法是需要循環指數次,也就是指數是多少就要循環計算多少次,而快速冪因爲利用了位移運算,只需要算“指數二進制位的位數”次,對於13來說,二進制是1101,有4位,就只需要計算4次,快速冪算法時間複雜度是O(logn)級別,對於普通冪需要計算一百萬次的10^{10^{6}}來說,快速冪只需要計算6次,這是速度上質的飛躍,但是需要多注意溢出的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章