高精度算法 学习笔记

高精度算法

高进度算法一共分为666个主题,分别是高精度加法、高精度减法、高精度乘法、高精度除法、高精度开根和压位。

一、高精度加法

现在有一道题目,如下

给你两个整数a和b,请你算出它们的和。
数据范围:1<=a,b<=10^1000

一看这道题,就感觉是基础的a+ba+ba+b问题,其实不然——数据范围肯定会爆。
那么我们怎么做呢?
我们回顾一下小学时候学的竖式加法。
假设a=145,b=44a=145,b=44a=145,b=44,竖式如下图
在这里插入图片描述
其实我们只用从最低位开始加,然后加到最高位就行了。
假设两个加数分别存入aaabbb数组,答案存入ccc数组,yyy表示进位,则
ci=(ai+bi+y) mod 10c_i=(a_i+b_i+y)\:mod\:10ci=(ai+bi+y)mod10
y=⌊ai+bi+y10⌋y=\lfloor \frac{a_i+b_i+y}{10}\rfloory=10ai+bi+y
那么就可以直接用一个循环做了。
时间复杂度为O(max(n,m))O(max(n,m))O(max(n,m))
nnnmmm分别表示两个数的位数。

二、高精度减法

那么高精度减法是不是也可以用竖式的办法解决呢,答案是对。
假设被减数a=100a=100a=100,减数b=78b=78b=78,竖式如下图
在这里插入图片描述
计算过程见右边。
其实我们只要判断一下当前这个位置是否够减,如果够,就减;否则,就加上101010再减,并把前一位减去111
程序如下:

for(int i=1;i<=n;i++)
{
	if(a[i]<b[i])
	{
		a[i]+=10;
		a[i+1]--;
	}
	c[i]=a[i]-b[i];
}

注意:最后要删除前导000
那如果a<ba<ba<b,怎么办?
因为a−b=−(b−a)a-b=-(b-a)ab=(ba),而b>ab>ab>a,所以我们只用计算b−ab-aba就行了,输出时在前面加个负号。
时间复杂度为O(max(n,m))O(max(n,m))O(max(n,m))
nnnmmm分别表示两个数的位数。

三、高精度乘法

上面我们解决了加法和减法,那么乘法是怎么样的呢?
乘法需要细心找规律才能找到。
假设乘数分别是121212131313,竖式如下图
在这里插入图片描述
我们看一下上图,可以发现一个规律:第iii位和第jjj位相乘的结果应该存在第i+j−1i+j-1i+j1位上。
举例一下:
111222乘以第222111,结果应该放在第222位,因为1+2−1=21+2-1=21+21=2
如果不明白可以看下图:
在这里插入图片描述
根据这个规律,我们就可以直接计算出答案,这里就不多说了。
注意:答案要累加进一个数组,因为可能会有i+j−1i+j-1i+j1重复的情况。
时间复杂度为O(nm)O(nm)O(nm)
nnnmmm分别表示两个乘数的位数。

四、高精度除法

高精度除法有两种方法,第一种是二分答案,第二种是利用减法来求。

第一种方法

由于乘法是除法的逆运算,所以我们直接寻找一个数看这个数是否满足乘法运算就行了。
找数的方法很简单,就是二分答案。
如果没学过二分答案,可以自己去网上学一学,以后我会出关于二分答案的内容。
二分答案时,我们只要做乘法就行了。
时间复杂度大概为O(nmlog⁡a2)O(nm\log_a^2)O(nmloga2)
nnn表示被除数的位数,mmm表示除数的位数,aaa表示被除数。
其实复杂度远没有这么多。

第二种方法

我们只用一次一次的用被除数减去除数,直到被减数等于000为止,答案就是次数。
这种时间复杂度很高,应该是O(ab)O(\frac{a}{b})O(ba)
aaa表示被除数,bbb表示除数。

五、高精度开根

高精度怎么开根呢,方法和高精度除法一样,都可以用二分答案来解决。
我们二分答案时,就只用算一下乘法,然后调整位置。
时间复杂度为O(nmlog⁡a2)O(n^m\log_a^2)O(nmloga2)
nnn表示被开方数的位数,mmm表示根指数,aaa表示被开方数。

六、压位

那么有什么方法可以使高精度算法的速度更快呢?
答案是,压位。
假如我们现在要算两个数的加法。
我们可以一次就算555位,这样只用开intintint
我们可以一次就算121212位,这样只用开longlonglong longlonglong
那么时间复杂度就变成了O(ab)O(\frac{a}{b})O(ba)
aaa表示原来的时间复杂度,bbb表示压位的位数。
这样就可以大大的缩短时间了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值