求 1234567891011121314151617181920 * 2019181716151413121110987654321 的乘積結果
分治乘法:最簡單的是karatsuba乘法,一般化以後有toom-cook乘法;
快速傅利葉變換fft:(為了避免精度問題,可以改用快速數論變換fntt),時間複雜度o(n lgn lglgn)。具體可參照schönhage–strassen algorithm;
中國剩餘定理:把每個數分解到一些互素的模上,然後每個同餘方程對應乘起來就行;
furer』s algorithm:在漸進意義上fntt還快的演算法。不過好像不太實用,本文就不作介紹了。大家可以參考維基百科fürer』s algorithm
7 8 9 6 5 2
× 3 2 1 1
-----------------
7 8 9 6 5 2 <---- 第1趟
7 8 9 6 5 2 <---- 第2趟
.......... <---- 第n趟
-----------------
? ? ? ? ? ? ? ? <---- 最後的值用另乙個陣列表示
第二步,將逐位相乘得到的結果,對應相加起來。
vectorbignumermultiply(vectorvec1, vectorvec2)
if(carry != 0)
int resultcarry = 0;
int count = 0;
int k = 0;
int m = 0;
int offset = vec2.size() - 1 - i;//加法的偏移位
vectormiddleresult;
//vec2每位乘法的結果與上一輪的求和結果相加,從右向左做加法並進製
while(k < single.size() || m < result.size())
if(m < result.size())
int sum = resultcarry + kv + mv;
middleresult.push_back(sum % 10);
resultcarry = sum / 10;
++count;
}if(resultcarry != 0)
result.clear();
result = middleresult;
}//將結果逆序
int len = result.size();
for(int i = 0; i < len / 2; ++i)
return result;
}
9 8
× 2 1
-------------
(9)(8) <---- 第1趟: 98×1的每一位結果
(18)(16) <---- 第2趟: 98×2的每一位結果
-------------
(18)(25)(8) <---- 這裡就是相對位的和,還沒有累加進製
vectorbignumbermultiply2(vectorvec1, vectorvec2)
}for(int k = result.size()-1; k>0; --k)}/*
例如10*10,result的第一位為0,數第一位為0沒有意義,所以刪掉
*/if(result[0] == 0)
return result;
}
!!注意:這裡的進製有個大坑,因為result陣列是從左到右記錄相對位的和(還沒有進製),而最後的進製是從右向左累加進製,這樣的話,如果最高位,也就是最左側那一位的累加結果需要進製的話,result陣列就沒有空間存放了。
result
放到第i+j+1位
大數相乘以及其高效演算法
測試用例 999 999 999999999999 999999999999 下面分析下999 999 6 5 4 6 5 4 36 30 24 30 25 20 24 20 16 這裡結果 就清楚了 但是要注意 asc 碼 最大是 128 所以要在加的時候就處理好 下面給出 普通 最一般的 nam...
大數乘法演算法
將大數當做字串進行處理,也就是將大數用十進位制字元陣列進行表示,然後模擬人們手工進行 豎式計算 的過程得到乘法的結果。include using namespace std define maxn 100 string multiply char line1,char line2 else if n...
大數問題 大數加法 與 大數乘法 最簡單大數乘法
大數加法很簡單,大叔乘法只是以大數加法為基礎的,光從難度來說,兩者差不多。先舉乙個簡單的例子 所以乘法就是每一位個位數相乘再乘以多少次方就可以了,這個多少次就是兩者的陣列位置的索引相加。看看關鍵 for int i 0 i alen i else result plus result,c heigh...