高精度算法(加减乘除)

高精度加法

高精度加法:反向存数组里,人工模拟两数相加

#include <iostream>
#include <string>
#include <vector>
using namespace std;
string s1, s2;
void add(vector<int>& A, vector<int>& B)
{
    vector<int> c;
    int t = 0;
    for(size_t i = 0; i < A.size() || i < B.size(); i++)
    {
        int ret = t;
        if(i < A.size()) ret += A[i];
        if(i < B.size()) ret += B[i];
        c.push_back(ret % 10);
        t = ret / 10;
    }
    if(t > 0) c.push_back(t);
    for(int i = c.size() - 1; i >= 0; i--)
    {
        cout << c[i];
    }
}
int main()
{
    vector<int> A;
    vector<int> B;
    cin >> s1 >> s2;
    for(int i = s1.size() - 1; i >= 0; i--) A.push_back(s1[i] - '0');
    for(int i = s2.size() - 1; i >= 0; i--) B.push_back(s2[i] - '0');
    add(A, B);
    return 0;
}

高精度减法

高精度减法
将大数字符串反向存在数组里,保证算法实现的时候为较大数 - 较小数,所以要添加一个比较函数 cmp ,如果题目是 小 - 大,要给最终结果前面加一个负号

  1. 比较函数 cmp ,保证算法里是 大 - 小;实现时,先判断 size 相等的情况,依次比较每一位,这些位中,如果哪一位不相等,就直接 return,如果不相等就直接返回 size 是否较大
  2. flag 标志,flag 的值决定是否在打印前先输出 -
  3. 前导零的处理,前导零是直接出现在 C 的末尾的,直接判断再 pop 即可
  4. 可以逆置,也可以不逆置,不逆置就反正输出即可

易错点:算法在实现的过程中,循环次数是 A.size()次,同时在循环里判断是否要减去 B[i],因为 B 有可能会越界,用 A来循环时为了保证 减完 B 之后方便将余下的借位处理掉

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
bool flag = 1;
bool Cmp(vector<int>& A, vector<int>& B)
{
    if(A.size() == B.size())
    {
        for(int i = A.size() - 1; i >= 0; i--)
        {
            if(A[i] != B[i]) return A[i] > B[i];
        }
    }
    return A.size() >= B.size(); // 包含 A == B
}
int Sub(vector<int>& A, vector<int>& B)
{
    vector<int> C;
    int t = 0; // 被借的位
    for(size_t i = 0; i < A.size(); i++)
    {
        t = A[i] - t;
        if(i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10); // 完美解决 t > 0 和 t < 0 的情况
        if(t < 0) t = 1;
        else t = 0;
    }
    for(size_t i = C.size(); i < A.size(); i++) C.push_back(A[i]);
    // 删除前导零
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    if(!flag) cout << "-";
    for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
int main()
{
    string a, b;
    cin >> a >> b;
    vector<int> A, B;
    for(int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    for(int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
    if(!Cmp(A, B)) 
    {
        flag = 0;
        swap(A, B);
    }
    Sub(A, B);
}

高精度乘法

高精度 * 低精度
将高精度存在数组里,低精度看作一个整体,模拟人工乘法,注意处理进位
当两个数中有 0 时,可特判,也可当前导零直接处理

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void Mul(vector<int>& A, int b)
{
    vector<int> C;
    int t = 0;
    for(size_t i = 0; i < A.size() || t > 0; i++)
    {
        if(i < A.size()) t = A[i] * b + t;
        C.push_back(t % 10);
        t /= 10;
    }
    while(C.size() > 1 && !C.back()) C.pop_back(); // 去除 A 或 b 为 0 时导致的前导 0 
    // reverse(C.begin(), C.end()); // 可以逆序后再按序输出, 也可以直接输出
    // for(size_t i = 0; i < C.size(); i++) cout << C[i]; 
    for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
int main()
{
    string a;
    int b;
    cin >> a >> b;
    vector<int> A;
    for(int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    Mul(A, b);
    return 0;
}

高精度除法

高精度 / 低精度 --> 商 和 余数,计算出的余数可以当作取模运算的结果

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void Div(vector<int>& A, int b)
{
    vector<int> C; // 存结果
    int t = 0;
    int rem; // 存余数
    for(int i = A.size() - 1; i >= 0; i--)
    {
        t = t * 10 + A[i];
        C.push_back(t / b);
        t %= b;
    }
    rem = t;
    reverse(C.begin(), C.end());
    while(C.size() > 1 && !C.back()) C.pop_back(); // 去除前导0
    for(int i = C.size() - 1; i >= 0; i--) cout << C[i]; // 输出商
    cout << endl << rem; // 输出余数 
}
int main()
{
    string a;
    int b;
    vector<int> A;
    cin >> a >> b;
    for(int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    Div(A, b);
    return 0;
}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值