D3.高精度

1.分类情况

A+B、A-B、A*a、A/b

A和B指的是超大超长整数,长度<=1e6;

a的值<=10000;

2.大整数的存储

int 变量肯定是存不了这么大的数的,做法是将大整数先存到string字符串,再使用字符串的访问方式,将每一位数存到数组中。

  • 因为加减涉及到数字的进位问题,要在数组最后加一个数是简单的,但是要算在数组第一个下标处进一位是麻烦的

3.运算

模拟人工加法的过程,每次计算Ai+Bi+t(t是上一次的进位,0或1)

高精度加法
  • 模板:
cpp 复制代码
vector<int> add(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    int t = 0;
    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(1);
    return C;
}
add(A,B);

注意在调用的时候和定义函数不同,直接传入就行,不用取址符号------引用

  • main函数中将字符串转化为数字
cpp 复制代码
	string a;//"12345"
    cin >> a;
    for(int i = a.size()-1; i >= 0; i --)
        A.push_back(a[i] - '0');//{5,4,3,2,1}

运算时还是根据ASCII表的数值,可以看到数组的字符形式的十进制和整形数字相差了一个字符 '0'.

高精度减法
cpp 复制代码
bool cmp(vector<int> &A, vector<int> &B)//判断是否有A>=B
{
    if(A.size() != B.size())  return A.size() > B.size();
    for(int i = A.size() - 1; i >= 0; i --)
        if(A[i] != B[i])
            return A[i] > B[i];
    return true;
}
vector<int> sub(vector<int> &A, vector<int> &B)
{
    vector<int> C;
    int t = 0;
    
    for(int i = 0; i < A.size(); i++)
    {
        t = A[i] - t;
        if(i < B.size()) t -= B[i];
        if(t >= 0)
        {
            C.push_back(t);
            t = 0;
        }
        else
        {
            C.push_back((t + 10) % 10);
            t = 1;
        }
    }
    
    //除去前导0
    while(C.size() > 1 && C.back() == 0)
        C.pop_back();
    return C;
}
高精度x低精度

高精度乘法的算法和人计算乘法时的过程稍有不同。Axb,A很长,使用string来储存,b很短,使用int即可。

将b看成一个整体去乘,而不是一位一位去乘。

cpp 复制代码
vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;
    int t = 0;
    for(int i = 0; i < A.size(); i ++)
    {
        t = t + A[i] * b;
        C.push_back(t % 10);
        t = t / 10;
    }
    
    //处理最后的进位
    while(t)
    {
        C.push_back(t % 10);
        t = t / 10;
    }
    
    return C;
}
//注意在main函数中考虑b=0的情况,否则输出0000而不是0
if(b)
    C = mul(A,b);
else 
    C.push_back(0);
高精度 / 低精度

模板

cpp 复制代码
vector<int> div(vector<int> &A, int b, int &x)
{
    vector<int> C;
    int r = 0;
    for(int i = A.size() - 1; i >= 0; i --)
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r = r % b;
    }
    x = r;
    reverse(C.begin(),C.end());
    
    while(C.size() > 1 && C.back() == 0)
        C.pop_back();
    return C;
}

注意除法是从A[]的高位开始除起,答案也是从高位开始存到C[]中。为了保证加减乘除格式的统一性,所以要在完成之后reverse(C.begin(),C.end());反转一下保证储存顺序,当然在输出的时候也是反着输出,注意会出现前导0的情况出现。

在加减乘除算法中,减法和除法 会出现前导零的情况;乘法会有特殊b = 0的存在.

4.刷题

对于未知的多组数据使用while(cin >> a >> b)每次循环的时候要清空vector数组!

对于已知的多组数据使用cin >> n;while(n --),同样在必要时每次循环清空数组,重新输入!

题外
  1. 表示2的i次方:1 << i 或者 #include<cmath> pow(2,i) 而不是2 ^ i.在 C++ 中,^ 是按位异或运算符.

  2. 注意字符串使用双引号" ",char类型使用单引号' '

  3. int 最多9位数;long long最多18位数

  4. 专门用于输出字符串的函数puts("No!");,并且它会自动在字符串末尾添加换行符。

cpp 复制代码
if (CC == A) puts("Yes");  
else puts("No");

==运算符可以比较两个vector是否相等。如果两个vector的大小相等,并且所有对应位置的元素都相等,那么这两个vector相等。

相关推荐
tainshuai1 小时前
用 KNN 算法解锁分类的奥秘:从电影类型到鸢尾花开
算法·分类·数据挖掘
Coovally AI模型快速验证7 小时前
农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
深度学习·算法·yolo·计算机视觉·transformer·无人机
mit6.8247 小时前
[openvela] Hello World :从零开始的完整实践与问题复盘
c++·嵌入式硬件
pusue_the_sun7 小时前
数据结构:二叉树oj练习
c语言·数据结构·算法·二叉树
RaymondZhao348 小时前
【全面推导】策略梯度算法:公式、偏差方差与进化
人工智能·深度学习·算法·机器学习·chatgpt
zhangfeng11338 小时前
DBSCAN算法详解和参数优化,基于密度的空间聚类算法,特别擅长处理不规则形状的聚类和噪声数据
算法·机器学习·聚类
啊阿狸不会拉杆9 小时前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
小学生的信奥之路9 小时前
洛谷P3817题解:贪心算法解决糖果分配问题
c++·算法·贪心算法
曙曙学编程10 小时前
stm32——GPIO
c语言·c++·stm32·单片机·嵌入式硬件
你知道网上冲浪吗10 小时前
【原创理论】Stochastic Coupled Dyadic System (SCDS):一个用于两性关系动力学建模的随机耦合系统框架
python·算法·数学建模·数值分析