取模運算的運算法則
(a + b) % p = (a % p + b % p) % p (1)背景:(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
求乙個數的指數,如果指數很大,根據」指數**遞增「的常識,計算結果會造成記憶體溢位
比如,求2的10000此方結果的最後三位,如果直接迴圈乘,一定會造成記憶體溢位
根據取模運算的運算法則,可以對每一次迴圈的結果取模,返回結果取模
long long normalpower(long long base,long long power)
return result%1000;
}
問題思考:
該演算法的時間複雜度是o(1),如果求2的1000000000次方,用時可能較長,寫乙個程式來測試一下算出結果到底用時多少
#include #include #include using namespace std;
/** * 普通的求冪函式
* @param base 底數
* @param power 指數
* @return 求冪結果的最後3位數表示的整數
*/long long normalpower(long long base, long long power)
return result % 1000;
}int main()
最後結果為17.61,將近18秒,18秒才算出結果,該演算法無法投入實際中使用
快速冪演算法初步
如果求指數很大的冪,快速冪演算法可以很快的求出結果
例如我們求3的十次方
如果用迴圈,需要十次運算
我們可以對3的十次方進行拆分,將3的十次方拆分為3*3的5次方,那麼這樣我們只需要多一次乘法,就可以減少一半的迴圈次數,如果指數比較大,減少一半的迴圈次數節約的時間很多
3^10=(3*3)*(3*3)*(3*3)*(3*3)*(3*3)
3^10=(3*3)^5
3^10=9^5
同理,我們可以對9的5次方再進行拆分,因為5是計數,我們無法對它進行折半拆分,這時可以先分出乙個9,變為9*9^4,再對9的4次方進行拆分
9^5=(9^4)*(9^1)
最後拆分為
9^5=(81^2)*(9^1)
9^5=(6561^1)*(9^1)
最後,我們的算式其實就變為
9^5=(6561^0)*(9^1)*(6561^1)=1*(9^1)*(6561^1)=(9^1)*(6561^1)=9*6561=59049
最後求出的冪結果實際上就是在變化過程中所有當指數為奇數時底數的乘積。
**
//求指數結果的最後三位
long long fastpower(long long base, long long power)else
} return result;
}
用這個演算法對上述的資料運算,時間為0.002秒,時間節約很大
快速冪演算法」壓榨效能優化「
可見上述**有重複操作
power = power/2;
base = base*base%1000;
且根據整數除法,奇數/2會向下取整
power = power - 1; ->> power = power / 2;
優化後演算法
//求指數結果的最後三位
long long fastpower(long long base, long long power)
power = power/2;
base = base*base%1000;
} return result;
}
位運算繼續優化
判斷奇偶,因為二進位制奇數最後一位為1,偶數最後一位為0,所以可以用該數&1是否為1判斷是否為奇數
同理,除以2,也能用位運算向右移動一位來運算
**
//求指數結果的最後三位
long long fastpower(long long base, long long power)
power = power >> 1;
base = base*base%1000;
} return result;
}
最後用時接近0秒 快速冪介紹及其模板
1.數的快速冪問題 所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求乙個冪式的模 餘 在程式設計過程中,經常要去求一些大數對於某個數的餘數,為了得到更快 計算範圍更大的演算法,產生了快速冪取模演算法。快速冪實際上是求解形如 an b這種形式。其中a和n可能會很大。普通解法時間複雜度為o...
快速排序及其優化
include include 呼叫c 自帶sort include include include using namespace std define max 1000000 define k 12 ifdef debug define new new normal block,file lin...
快速排序及其優化
快速排序是比較經典 常用的演算法,下面簡要介紹其思路。對於乙個陣列,選取某個元素作為切分元素 比如第乙個元素 然後把比這個元素小的都放到它前面,比這個元素大的都放到它後面,這樣切分元素的最終位置就確定了,並且陣列被劃分為兩個子陣列。然後再用同樣的方法分別對子陣列進行排序,最終整個陣列將變成有序的。這...