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相等。

相关推荐
好奇龙猫34 分钟前
【学习AI-相关路程-mnist手写数字分类-win-硬件:windows-自我学习AI-实验步骤-全连接神经网络(BPnetwork)-操作流程(3) 】
人工智能·算法
霁月风1 小时前
设计模式——适配器模式
c++·适配器模式
sp_fyf_20241 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
香菜大丸1 小时前
链表的归并排序
数据结构·算法·链表
jrrz08282 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time2 小时前
golang学习2
算法
咖啡里的茶i2 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1072 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客2 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
南宫生3 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法