現在考慮一個類似的問題:兩個n位的整數相乘。例2-4展示了使用國小課堂上學過的算法實作的乘法運算,其中n位數字的表示方法與之前的加法一樣。
例2-4:mult乘法的Java實作
public static void mult (int[] n1, int[] n2, int[] result) {
int pos = result.length-1;
// 清除所有的值
for (int i = 0; i < result.length; i++) { result[i] = 0; }
for (int m = n1.length-1; m>=0; m--) {
int off = n1.length-1 - m;
for (int n = n2.length-1; n>=0; n--,off++) {
}
同樣的,這裡也會給出另外一種實作算法——times。這種算法避免了取模運算的高費用,并且忽略了當n1[m]等于0時不必要的内層計算(注意,這裡并沒有給出times算法實作,讀者可以在提供的代碼庫中找到它)。times算法包含了203行生成的Java代碼來消除兩個取模操作。那麼在需要額外的費用維護和管理生成代碼時,這種衍生算法還能夠減少總的性能費用嗎?
表2-4給出了這些乘法算法的性能,乘法所使用的資料與加法使用的随機生成資料一緻。圖2-4采用圖形化的方式來描述算法性能,可以看到,抛物曲線是平方級算法的典型标志。
圖2-4:比較mult和times
如圖2-4所示,雖然times衍生算法的速度是mult算法的1/2,但是times和mult展現了相同的漸近性能。mult2n / multn的比率大約是4,這證明了乘法的性能是平方級的。我們定義t(n)表示乘法算法在輸入規模為n時的實際執行時間。根據這個定義,對于所有的n > n0來說,必然存在某些常數c(c > 0),滿足t(n) ≤ c*n2。我們不需要知道c和n0的實際值是多少,隻需要知道它們必然存在即可。這個mult算法實作在我們的平台上執行時,常數c為1/7,n0為16。
需要再次說明的是,修改算法實作來提升效率并不會改變算法是平方級性能的事實。盡管如此,還是有其他的算法(Zuras,1994)可以讓n位數相乘的明顯速度快于平方級。對于像資料加密這種需要頻繁實作大數乘法的應用,這類算法非常重要。