蓝桥杯算法笔记<8> 高精度系列

高精度加法

高精度加法归根结底是一个模拟人工加法的过程
大致要点如下
Ⅰ.使用两个数组a,b倒序存储输入的数字,这样能比较方便地处理进位问题
Ⅱ.在进行加法地过程中,使用一个指针 i 指向当前正在相加的位置,并开一个t变量存储进位
Ⅲ.如果a[i]b[i]存在,就使得t加上 a[i]b[i]
Ⅳ.向结果数组c中加入t%10
Ⅴ.t=t/10 完成进位,为下一轮运算的进位作准备
Ⅵ.(易错)在循环相加各个位之后,t中仍然可能有残余的数字没有加入到结果数组中,如50 + 50 这种场景,循环后c数组中为00,t为1,所以需要手动添加剩余的值。
实现代码:

vector<int> add(vector<int> a,vector<int> b)
{
    int t=0;
    vector<int> c;
    for(int i=0;i<a.size()||i<b.size();i++)  
    {
        if(i<a.size()) t+=a[i];
        if(i<b.size()) t+=b[i];
           
        c.push_back(t%10);
        t/=10;
    }
    if(t)
    c.push_back(t);
    return c;
}

高精度减法

高精度减法也是一个模拟人工减法的过程,但是减法有可能出现负数,实现起来比高精度加法复杂
大致分为以下几个过程

比较两个数组谁更大

实现如下:

bool cmp(vector<int> &a,vector<int> &b)
{
	/*位数多的大*/
	if(a.size()!=b.size())
		return a.size()>b.size();	
	/*位数相同则逐位比较*/
	for(int i=0;i<a.size();i++)
		if(a[i]!=b[i])
			return a[i]>b[i];
	/*经历了上面两步都还没有返回,说明相等,直接return*/
	return true;
}

较大的a[]和较小的b[],进行高精度减法

Ⅰ.需要开一个int t 来记录之前是否有过借位
Ⅱ.每次运算,分够不够减两种情况

如
    A3 A2 A1 A0
-      B2 B1 B0
----------------------
						 |--- if(Ai-Bi>=0)  Ai-Bi-t
对于每个Ai-Bi-t分两种情况 |
						  |---if(Ai-Bi<0)  Ai-Bi+10-t (需要借一位)
vector<int> mine(vector<int>& a, vector<int> &b)
{
	vector<int> c;
	for(int i=0,t=0;i<a.size();i++)
	{
			//进位
		t=a[i]-t;
		if(i<b.size()) t-=b[i];  //由于b较小,可能没有第i位,所以在减b之前判断
		c.push_back((t+10)%10); //两种情况合二为一写
		/*
		    如果 t (或者说a[i]-b[i]-t)< 0  这种情况需要借位 体现在本轮循环,即push_back(t+10) 并在循环后使t为1
		    如果 t (或者说a[i]-b[i]-t)> 0  这种情况无需要借位 体现在本轮循环中,即是push_back(t) 并在循环后使t为0
		    这两种情况都能合二为一地写成push_back((t+10)%10)
		*/
		if(t<0) t=1;
		else t=0;
	}
	
	/*去除前导零*/
	while(c.size()>1&&c.back()==0) c.pop_back();
	return c;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值