从零开始的算法学习生活——①高精度运算(1)


前言

在摸了这么久鱼后,本蒟蒻也下定决心要开始好好学习算法了!从这第一篇博客开始,从零开始记录我的算法学习生活,权当是给自己做做笔记,文章或许有错误疏漏的地方,还请多多包容!


一、怎样实现高精度运算?

我们在平时存储一个整数时,通常使用int类型来储存,而一个四字节的int最多也只能储存到2^31-1 = 2,147,483,647不过十位而已。数字稍微大一点时,还可以使用long long类型。而需要存储或者使用更大的整数时,就需要利用数组来模拟非常长的整数。

二、例题

P1601 A+B Problem(高精)

题目描述
高精度加法,相当于a+b problem,不用考虑负数.

输入格式
分两行输入。数据范围: a , b ≤ 1 0 500 a,b\le 10^{500} a,b10500

输出格式
输出只有一行,代表 a + b a+b a+b 的值

输入输出样例
输入 # 1 1 1
1 1 1
1 1 1
输出 # 1 1 1
2 2 2
输入 # 2 2 2
1001 1001 1001
9099 9099 9099
输出 # 2 2 2
10100 10100 10100

1.分析

题面没啥好说的,一个A+B problem的高精度版本。

该题目需要储存500位大的非负整数,一般的存储方法显然是行不通的,这里就要利用数组来进行模拟存储。

那么要如何实现两个大数的加法呢?类似于竖式加法,从低位至高位,模拟每一位的加法与进位。对于十进制加法,当某一位加和大于9时将产生进位,所以要从低位至高位依次判断是否要向前进位。

举个例子,539+658=1197,下表是每一位的运算过程。

第3位第2位第1位第0位
a539
b658
中间运算结果11817
处理进位11197
处理进位21197
结果1197

同时这里也可以看出,必须从低位至高位运算,否则可能会产生顺序上的错误,只有处理了低位的进位,才能知道高位是否需要进位。

2.AC代码

附上AC代码

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int max_n = 502;//最大位数
int a[max_n],b[max_n],c[max_n];
int main()
{
    string A,B;
    cin>>A>>B;
    int len = max(A.length(),B.length());
    for (int i = 0,j = A.length()-1; j>=0; i++,j--)
        a[i] = A[j] - '0';
    for (int i = 0,j = B.length()-1; j>=0; i++,j--)
        b[i] = B[j] - '0';
    for (int i = 0; i<len ; i++ ) //从低位至高位依次作加法运算
    {
        c[i]+= a[i]+b[i];//当前位相加
        c[i+1] = c[i]/10;//若当前位大于十,则向前进位
        c[i]%=10;//保留个位数
    }
    if(c[len])len++;//若最高位产生进位,则长度可能发生改变
    while(len--)cout<<c[len];
    return 0;
}


总结

高精度整数加法通过数组进行模拟大数的存储,加法实质上是模拟每一位的加法与进位,保留当前位的个位,将十位(如果有)加到下一位。

第一篇博客就到这里结束啦,题目比较简单基础,但没有良好的基础打地基,所有以后的学习不过是空中楼阁罢了。新的一年新的开始,一步一个脚印向前进发吧!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值