Java实现Multiplication Of Large Integers《大整数乘法》算法

问题描述:假设有两个大整数X、Y,现在要求X*Y的乘积

简介:大整数乘法是一种运算数学中的一种算法,将大整数式子分解为若干个整数表达式,使之可以通过乘法解决

算法设计思想:

①理想状态:当X、Y的位数相同时:

现在要求X*Y的乘积,小学的算法就是把X与Y中的每一项去乘,但是这样的乘法所需的时间复杂度为O(N^2),(因为每一位要逐个去乘),所以效率比较低下。那我们可以采用分治的算法,将X、Y拆分成四部分,如下图:

 则X可表示为:X=A*10^(n/2)+B   同理Y也可以表示出来:Y=C*10^(n/2)+D

 所以将一个大的整数分成两部分,问题规模减小,直接相乘就可以写成:

但是如果直接算AD+BC,效率太低(需要计算4次n/2位整数的乘法,以及三次加法),所以对·AD+BC进行分解优化后得:

 

 计算成本:3次n/2位乘法,6次不超过n位加减法,2次移位,所有加法和移位共计O(n)次运算。由此可得:

 

非理想状态:X、Y的位数不相同

依然采用分治的算法,将X、Y分别拆分为A与B、C与D,如下图: 

 

计算成本:需要进行2次xn0的乘法(AC、AD各一次)、2次yn0的乘法(AC、BC各一次)和3次加法,因而该算法的时间复杂度为 

 对AD+BC进行分解优化 :

得到时间复杂度:T(m+n)=O(nlog3)=O(n1.59) 

 源代码展示(练习不靠谱版):

package MultiplicationOfLargeIntegers;

import java.util.Scanner;

public class multiplicationOfLargeIntegers {
	public static void main(String args[])
	{
		Scanner in=new Scanner(System.in);
		System.out.println("请输入x值:");
		long x=in.nextInt();
		long n=0;
		long temp1=x;
		while(temp1!=0) {
			n++;
			temp1=temp1/10;
		}//计算整型长度
		System.out.println("请输入y值:");
		long y=in.nextInt();
		long m=0;
		long temp2=y;
		while(temp2!=0) {
			m++;
			temp2=temp2/10;
		}
		long result=multiplication(x,y,n,m);
		System.out.println("x*y的值是:"+result);
		in.close();	
	}
	public static long multiplication(long a,long b,long n,long m)
	{
		long s;//符号
		if((a>0&&b>0)||(a<0&&b<0))
		{
			s=1;
		}
		else {
			s=-1;
		}
		a=Math.abs(a); //不考虑符号
		b=Math.abs(b);
		if(n==0 || m==0)//递归出口
		{
			return 0;
		}
		else if(n==1 || m==1)//当a,b中只有一位数时
		{
			return s*a*b;
		}
		else{
			long n1=n/2;//a的低半位数
			long n2=n-n/2;//a的高半位数
			long m1=m/2;//b的低半位数
			long m2=m-m/2;//b的高半位数
			long A= a/(int)(Math.pow(10, n1)); //高半位数值
			long B=a%(int)(Math.pow(10, n1));//低半位数值
			long C=b/(int)(Math.pow(10, m1));//pow支持的数据类型为double,所以在pow函数前加上(long)
			long D=b%(int)(Math.pow(10, m1));
			long AC=multiplication(A,C,n2,m2);
			long BD=multiplication(B,D,n1,m1);
			long ABCD=multiplication(A*(long)(Math.pow(10, n1))-B,D-C*(long)(Math.pow(10, m1)),n1,m1);
			return  s*(2*AC*(int)(Math.pow(10,n1+m1))+ABCD+2*BD);
		}
		
	}
}

个人练习归纳习惯,欢迎大家讨论反馈! 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值