算法设计与分析:大整数乘法

大整数乘法

声明:本文仅个人笔记

参考链接:
https://www.cnblogs.com/McQueen1987/p/3348426.html
https://blog.csdn.net/sinat_32716451/article/details/84174455

题目和分析:

这里面的O(n^2)就是下面的我自己画的小学乘法计算复杂度示意图

注意:

  • T(n)代表规模为n的问题,系数4表示问题缩小到T(n/2)时,包含四次乘法(上式中AC/AD/BC/BD四次
  • 这里第一次是进行了4次的n/2的整数乘法---->4T(n/2)
  • 3次2n位的加法,2次移位----->O(n)
  • 而后来的改进主要是改进的是递归孩子乘法的次数由4变为3
  • 所以当n>1的时候主要有T(n)=4T(n/2)变成了3T(n/2)
  • 此时T(n)从O(nlog4)变成了O(nlog3),这里的log4和log3其实是以2为底的

这里有个问题就是4次n/2乘法怎么变成n^log4的,等想好再来接着编辑吧

代码上菜:

注意这里的代码是十进制大整数进行相乘,而课本给出的是二进制机器数进行相乘

XY = (A10^(n/2) + B)( C10^(n/2) + D)
= AC10^n + AD10^(n/2) + BC10^(n/2) + BD
= A
C10^n + ((A-B)(D-C) + AC + BD)10(n/2) + BD
上面的最后一行理解为“先减后加”

而且这里代码里面是对AD+BC的另外一种形式的推导即“先加后减”

package cn.htu.test;

public class BigDataRide {
 
	public static int sign(long a) {
 
		return a < 0 ? -1 : 1;
 
	}
	
	public static double bigdataride(long x,long y,int n) {
 
		x = Math.abs(x);//符号交给sign函数处理,我们只处理正数
 
		y = Math.abs(y);
 
		if (n == 1) {
			
			return x * y;
 
		}
 
		else {
			if (n%2==1) {
				n = n - 1; //对奇数的操作;在课本的分析中,所做假设是n是2的幂
			}
			long a = x / Math.round(Math.pow( 10 , (n / 2)));//移位操作,可以理解为小数点相对左移了
 
			long b = x - a * Math.round(Math.pow( 10 , (n / 2)));//得到的就是低位数值
 
			long c = y / Math.round(Math.pow( 10 , (n / 2)));
 
			long d = y - c * Math.round(Math.pow( 10 , (n / 2)));
 
			double ac = bigdataride(a,c,n/2);//递归计算a*c
 
			double bd = bigdataride(b,d,n/2);//计算b*d
 
			long sum_ab = a + b;
 
			long sum_cd = c + d;
 
			double abcd = bigdataride(sum_ab,sum_cd,n/2);
			//以上总共调用了3次递归函数即log3
			
			//原来推导式里面的((A-B)(D-C)+AC+BD)的结果其实就是先减再加,下面的是先加再减
			//即(A+B)(C+D)-AC-BD == AD+BC
 
			return (ac*Math.pow(10,n) + (abcd - ac - bd)*Math.pow(10,n/2) +bd);
 
		}
 
	}
 
	public static void main(String[] args) {
 
		// 十进制大整数相乘(非用户输入型)

		long x = 12234L;
 
		long y = 45243L;
 
		String xString = String.valueOf(x);//转为字符串,计算位数存到n
 
		int n = xString.length();
 
		long sig = sign(x)*sign(y);//sign返回参数的正负,sig取值范围为{1,-1}
 
		double s = bigdataride(x,y,n);//s是数值部分
 
		System.out.println("大数相乘的计算结果为:"+s*sig);
 
 
	}
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值