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

相关推荐
林的快手7 分钟前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
FeboReigns8 分钟前
C++简明教程(4)(Hello World)
c语言·c++
FeboReigns9 分钟前
C++简明教程(10)(初识类)
c语言·开发语言·c++
千天夜16 分钟前
多源多点路径规划:基于启发式动态生成树算法的实现
算法·机器学习·动态规划
zh路西法18 分钟前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(二):从FSM开始的2D游戏角色操控底层源码编写
c++·游戏·unity·设计模式·状态模式
从以前21 分钟前
准备考试:解决大学入学考试问题
数据结构·python·算法
.Vcoistnt44 分钟前
Codeforces Round 994 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划
小k_不小1 小时前
C++面试八股文:指针与引用的区别
c++·面试
沐泽Mu1 小时前
嵌入式学习-QT-Day07
c++·qt·学习·命令模式
ALISHENGYA1 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(实战训练三)
数据结构·c++·算法·图论