使用分治法實現大數相乘,不要求兩數長度一致。時間複雜度爲T(N)=O(N^1.59).
#include <iostream>
#include <math.h>
using namespace std;
int SIGN(long A);
long CalculateUnSame(long X, long Y, int xn, int yn);
int main(int argc, char *argv[])
{
cout<<"please input two numbers: \nX="; //若是用getline獲取string,則應用stringstream轉爲long.
long X = 0;
cin>>X;
cout<<"Y=";
long Y = 0;
cin>>Y;
int xn = 1;
long x1 = X;
while( x1 / 10 > 0) //求長度
{
xn++;
x1 /= 10;
}
int yn = 1;
long y1 = Y;
while( y1 / 10 > 0)
{
yn++;
y1 /= 10;
}
long sum = CalculateUnSame(X, Y, xn,yn);
cout<<"normal mult_result X * Y = "<<X<<" * "<<Y<<" = "<<X * Y<<endl;
cout<<"divide and conqure X * Y = "<<X<<" * "<<Y<<" = "<<sum<<endl;
return 0;
}
int SIGN(long A)
{
return A > 0 ? 1 : -1;
}
long CalculateUnSame(long X, long Y, int xn, int yn)
{
int sign = SIGN(X) * SIGN(Y);
X = abs(X);
Y = abs(Y);
if (X == 0 || Y == 0)
return 0;
else if (xn == 1 || yn == 1)
return sign * X * Y;
else
{
int xn0 = xn / 2, yn0 = yn / 2;
int xn1 = xn - xn0, yn1 = yn - yn0;
long A = (long)(X / pow(10, xn0));
long B = (long)(X % (long)pow(10, xn0));
long C = (long)(Y / pow(10, yn0));
long D = (long)(Y % (long)pow(10, yn0));
long AC = CalculateUnSame(A, C, xn1, yn1);
long BD = CalculateUnSame(B, D, xn0, yn0);
long ABCD = CalculateUnSame((long)(A * pow(10, xn0) - B), (long)(D - C * pow(10, yn0)), xn1, yn1);
return (long) sign * (2 * AC * pow(10, (xn0 + yn0)) + ABCD + 2 * BD);
}
}
上述代碼中數據類型定義爲long,而在limits.h中可以看到:long型數最大值爲2147483647,最小值爲-2147483648
開根號得46340,五位數。所以上面代碼計算結果大於 LONG_MAX時就會溢出。
將數據類型改爲long long可以計算的結果爲:最大值9223372036854775807,最小值-9223372036854775808
根號9223372036854775807得到3037000500,10位數。
不管是long還是long long都有長度限制。所以本算法並不能真正做到大數相乘。進一步的改進是將數據都用string來傳遞。