题目:
用分治算法编程实现两个n位十进制大整数的乘法运算。
思路:
参考大整数乘法的详解
伪码:
Function MulOfLargeInt(X,Y,n)**
输入:n位乘数X,Y,位数n
输出:XY的乘积
**1.if X = 0 or Y = 0 ; return 0
2.else if digit = 0 ; return XY
3.else
4.A ← X的前n/2位
5.B ← X的后n/2位
6.C ← Y的前n/2位
7.D ← Y的后n/2位
8.AC ← MulOfLargeInt(A,C,n/2)//AC
9.BD ← MulOfLargeInt(B,D,n/2)//B*D
10.ABCD ← MulOfLargeInt((A-B),(D-C),n/2)+AC+BD
11.if n为奇数
12.XY ← AC * 10 ^ (n-1) + ((A-B)(D-C)+AC + BD) * 10 ^ n/2 + BD
13.else n为偶数
14.XY ← AC * 10 ^ n + ((A-B)(D-C) + AC + BD) * 10 ^ n/2 + BD
时间复杂度:O(n^log3)
实现:
#include<stdio.h>
#include<math.h>
long long divide_conquer(long long X, long long Y, int digit){
long long A,B,C,D,AC,BD,ABCD;
//printf("x=%lld\ty=%lld\t位数=%d\t\n",X,Y,digit);
if(X == 0 || Y == 0){
return 0;
}else if(digit == 1){
return X*Y;
}else{
A = X/pow(10,digit / 2);
//printf("a=%lld\t",A);
B = X % (int)pow(10,digit / 2);
//printf("b=%lld\t",B);
C = Y / pow(10,digit / 2);
//printf("c=%lld\t",C);
D = Y % (int)pow(10,digit / 2);
//printf("d=%lld\t\n",D);
AC = divide_conquer(A,C,digit / 2);
//printf("ac=%lld\t",AC);
BD = divide_conquer(B,D,digit / 2);
//printf("bd=%lld\t\n",BD);
//printf("A-B = %lld\t",A-B);
//printf("D-C = %lld\n",D-C);
ABCD = divide_conquer((A - B),(D - C),digit / 2) + AC + BD;
//如果是位数是偶数,公式为:XY = AC*10的n次方 +((A-B)(D-C)+AC+BD)*10的n/2次方 + BD
//如果是位数是奇数,公式为:XY = AC*10的(n-1)次方 +((A-B)(D-C)+AC+BD)*10的n/2次方 + BD
if(digit%2 == 0){
//printf("A=%lld\tB=%lld\tC=%lld\tD=%lld\tAC=%lld\tBD=%lld\tABCD=%lld\t\n",A,B,C,D,AC,BD,ABCD);
//printf("t=%lld\n",(AC * pow(10,digit) + ABCD * pow(10,digit / 2) + BD));
return AC * pow(10,digit) + ABCD * pow(10,digit / 2) + BD;
}else{
//printf("A=%lld\tB=%lld\tC=%lld\tD=%lld\tAC=%lld\tBD=%lld\tABCD=%lld\t\n",A,B,C,D,AC,BD,ABCD);
//printf("t=%lld\n",(AC * pow(10,digit-1) + ABCD * pow(10,digit / 2) + BD));
return AC * pow(10,digit-1) + ABCD * pow(10,digit / 2) + BD;
}
}
}
int main(){
long long x,y,product;
int digit;
printf("请输入X:");
scanf("%lld",&x);
printf("请输入Y:");
scanf("%lld",&y);
int t = x;
do{
digit++;
t = t / 10;
}while(t != 0);
printf("X=%lld\tY=%lld\tdigit=%d\t\n",x,y,digit);
product = divide_conquer(x,y,digit);
printf("X * Y = %lld",product);
}
遇到的问题:
1、如果只用int类型的话,6位数的乘法运算会出现负值。
2、如果是位数是偶数,公式为:XY = AC*10的n次方 +((A-B)(D-C)+AC+BD)10的n/2次方 + BD ;
如果是位数是奇数,公式为:XY = AC10的(n-1)次方 +((A-B)(D-C)+AC+BD)*10的n/2次方 + BD 。