算法设计——大整数乘法(分治)

关于这个乘法,重点就是公式的化简
使得子问题的规模减小

问题

求X*Y的值

思路

将X、Y分别分为两部分
即X=a10^n/2+b ,n为X的位数
Y=c
10^m/2+d ,m为Y的位数
理想情况下m=n,那么
XY=ac10^n + bd+ (ad+bc)*10^n/2
(ad+bc)*10^n/2 =((a-b)(d-c)+ac+bd)*10^n/2
由此推广到XY位数不相等的情况

代码实现

包括位数相同与位数不同的情况


#include<stdio.h>
#include<string.h>
#include<math.h>
int sign(long A);
void samenumber();
void unsamenumber();
long long int  jisuansame(long x,long y,int n);
long long int jisuanunsame(long x,long y,int xn,int yn);

int main()
{
	samenumber();//相同位数 
	unsamenumber();//不同位数 
	return 0;
}

int sign(long A)//符号判断 
{
	if(A>0)
	    return 1;
	else return -1;
}

void samenumber()
{
	long x=0,y=0,sum=0;
	int n=0;
	printf("理想状态下用法:x=");
	scanf("%d",&x);
	printf("y=");
	scanf("%d",&y);
	printf("整数位数n=");
	scanf("%d",&n);
	
	sum=jisuansame(x,y,n);
	printf("%d\n",sum);
}

long jisuansame(long x,long y,int n)//计算相同位数 
{
	int fuhao=sign(x)*sign(y);
	
	x=labs(x);
	y=labs(y);
	
	if(x==0||y==0) return 0;
	else if(n==1) return fuhao*x*y;
	else
	{
		long a=(long)(x/pow(10,n/2));
    	long b=(x%(long)pow(10,n/2));
	    long c=(long)(y/pow(10,n/2));
	    long d=(y%(long)pow(10,n/2));
	    
	    long ac=jisuansame(a,c,n/2);
	    long bd=jisuansame(b,d,n/2);
	    long abcd=jisuansame((a-b),(d-c),n/2)+ac+bd;
	    return (long)(fuhao*(ac*pow(10,n)+abcd*pow(10,n/2)+bd));
	}	
}

void unsamenumber()//不同位数 
{
	long long x,y,sum=0;
	int xn,yn;
	printf("不理想状态下用法:x=");
	scanf("%lld",&x);
	printf("y=");
	scanf("%lld",&y);
	printf("x整数位数xn=");
	scanf("%d",&xn);
	printf("y整数位数yn=");
	scanf("%d",&yn);
	
	sum=jisuanunsame(x,y,xn,yn);
	printf("%lld",sum);
}

long long int jisuanunsame(long x,long y,int xn,int yn)//计算不同位数 
{
	int fuhao=sign(x)*sign(y);
	
	x=labs(x);
	y=labs(y);
	 
	if(x==0||y==0) return 0;
	else if(xn==1||yn==1) return fuhao*x*y;
	else
	{
		int xn0=xn/2,yn0=yn/2;
		int xn1=xn-xn0,yn1=yn-yn0;
		long a=x/pow(10,xn0);
    	long b=x%(long)pow(10,xn0);
	    long c=y/pow(10,yn0);
    	long d=y%(long)pow(10,yn0);
    	
    	long ac=jisuanunsame(a,c,xn1,yn1);
    	long bd=jisuanunsame(b,d,xn0,yn0);
    	long abcd=jisuanunsame(a*pow(10,xn/2)-b,d-c*pow(10,yn0),xn1,yn1);
    	
    	return (long long int)(fuhao*(2*ac*pow(10,(xn0+yn0))+abcd+2*bd));
	}
	
	
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值