AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 793. 高精度乘法 A x b 和 A x B 的模版(大数相加、大数相乘通用模板)    原题链接    简单

作者: 作者的头像   捡到一束光 ,  2020-05-26 11:00:43 ,  所有人可见 ,  阅读 16930


339


326

高精度 X 低精度

#include <iostream>
#include <vector>

using namespace std;

vector <int> mul(vector <int> & A, int b) {
    vector <int> C;

    int t = 0;
    for (int i = 0; i < A.size(); i ++) {
        t += A[i] * b;       // t + A[i] * b = 7218
        C.push_back(t % 10); // 只取个位 8
        t /= 10;             // 721 看作 进位
    }

    while (t) {            // 处理最后剩余的 t
        C.push_back(t % 10);
        t /= 10;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;
}

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');

    auto C = mul(A, b);

    for (int i = C.size() - 1; i >= 0; i --) {
        cout << C[i];
    }

    return 0;
}

高精度 X 高精度

#include <iostream>
#include <vector>

using namespace std;

vector<int> mul(vector<int> &A, vector<int> &B) {
    vector<int> C(A.size() + B.size() + 7, 0); // 初始化为 0,C的size可以大一点

    for (int i = 0; i < A.size(); i++)
        for (int j = 0; j < B.size(); j++)
            C[i + j] += A[i] * B[j];

    int t = 0;
    for (int i = 0; i < C.size(); i++) { // i = C.size() - 1时 t 一定小于 10
        t += C[i];
        C[i] = t % 10;
        t /= 10;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back(); // 必须要去前导 0,因为最高位很可能是 0
    return C;
}

int main() {
    string a, b;
    cin >> a >> b; // a = "1222323", b = "2323423423"

    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');

    auto C = mul(A, B);

    for (int i = C.size() - 1; i >= 0; i--)
        cout << C[i];

    return 0;
}

更新:大数相加A+B和大数相乘A*B通用模板

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> add(vector<int> A, vector<int> B) {
    // A: 4 3 2 1
    // B: 6 5
    vector<int> C(max(A.size(), B.size()) + 7, 0);  // 数组C开大一点没事,反正可以去前导零的
    for (int i = 0; i < A.size(); i ++) C[i] += A[i];
    for (int i = 0; i < B.size(); i ++) C[i] += B[i];

    // 处理进位
    for (int i = 0; i + 1 < C.size(); i ++) {
        C[i + 1] += C[i] / 10;
        C[i] %= 10;
    }

    // 处理前导零
    while (C.size() > 1 && C.back() == 0) C.pop_back();

    reverse(C.begin(), C.end());
    return C;
}

vector<int> mul(vector<int> A, vector<int> B) {
    // A: 4 3 2 1
    // B: 6 5
    vector<int> C(A.size() + B.size() + 7, 0);  // 数组C开大一点没事,反正可以去前导零的
    for (int i = 0; i < A.size(); i ++) {
        for (int j = 0; j < B.size(); j ++) {
            C[i + j] += A[i] * B[j];
        }
    }

    // 处理进位
    for (int i = 0; i + 1 < C.size(); i ++) {
        C[i + 1] += C[i] / 10;
        C[i] %= 10;
    }

    // 处理前导零 "0000" 去掉前导零
    while (C.size() > 1 && C.back() == 0) C.pop_back();

    reverse(C.begin(), C.end());
    return C;
}

int main() {
    string s1 = "9899", s2 = "100";

    vector<int> A, B;
    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');

    vector<int> C = add(A, B);
    cout << s1 << "+" << s2 << "=";
    for (int i = 0; i < C.size(); i ++) cout << C[i];
    cout << endl;

    C = mul(A, B);
    cout << s1 << "*" << s2 << "=";
    for (int i = 0; i < C.size(); i ++) cout << C[i];
    cout << endl;

    return 0;
}

附:A*B图解
Snipaste_2022-03-15_11-00-22.png

81 评论


用户头像
Shuken   2023-02-09 18:42      6    踩      回复

C数组的空间其实可以开成A.size()+B.size()就完全足够了,因为A*B的最大长度就是二者的长度之和。

用户头像
好好学习_98   2023-07-19 17:00         踩      回复

合理的,不可能超过二者长度之和


用户头像
JJJOKERQQQ   2022-09-08 11:34      4    踩      回复

大佬 高精度 X 低精度
while (t) { // 处理最后剩余的 t
C.push_back(t % 10);
t /= 10;
}
是不是等价于 if(t) C.push_back(t); 写成这个也可以吧

用户头像
码农耕地人   2022-12-16 20:38         踩      回复

和我想得一样,但是我这样做结果的最高位就是出不来,不知道出啥问题了

用户头像
码农耕地人   2022-12-16 20:39         踩      回复

不对,应该是if(!t) C.push_back(t);

用户头像
using_ll   2023-01-27 14:14      2    踩      回复

在这题应该是等价的,但是如果需要用到这个结果运算,就会出错,比如最后的 t 是 大于10的,你vector中存储的就是大于10的数,如果同时进行其他高精度操作时,可能会溢出。做这题,你就理解了 https://www.luogu.com.cn/problem/P1009

用户头像
白茶坔乌龙   2023-01-31 19:29      3    踩      回复

不等价,最后的t可能很大,但每次只能取一位,所以要用while

用户头像
风_963   9个月前    回复了 using_ll 的评论         踩      回复

这道题是不是高精度乘以低精度函数和高精度函数相加然后迭代就可以写出来呢

用户头像
y差c   6个月前         踩      回复

不等价!! t很有可能超过1位,然后需要不停插入,要用while


用户头像
Dyd62446   5个月前      2    踩      回复

太清楚了吧
那个图


用户头像
洛喑   2023-07-05 12:04      2    踩      回复

大数×大数中是不是忘记把t中剩下的位给进完了啊qwq
114514×1919810这样子就会错掉


用户头像
Pobz   2023-01-05 18:35      2    踩      回复

###tql


用户头像
iqnus   7天前      1    踩      回复

高*低
乘法只有b=0才需要高位弹出,所以mul开头直接加一个判断返回0也可以
if(!b)
{
C.push_back(0);
return C;
}


用户头像
郭子羽   2023-02-26 08:44      1    踩      回复

# 直接收藏!!!

用户头像
郭子羽   2023-02-26 08:44      1    踩      回复

## hhhhh


用户头像
y_96   2022-11-26 16:51      1    踩      回复

图解很清楚


用户头像
StkOvflow   2022-07-22 19:04      1    踩      回复

for (int i = 0; i < A.size(); i ++)这句如果是i<A.size()||t,是不是不用处理剩下的t了

用户头像
cxposition   2022-08-26 22:02      1    踩      回复

是的,这样写就好

for(int i = 0; i < a.size() || t; i ++ ){
        if(i < a.size()) t += a[i] * b; 
        c.push_back(t % 10);
        t /= 10;
    }
用户头像
cxposition   2022-08-26 22:03         踩      回复

加个判断,防止数组下标越界


用户头像
没对象的野指针   2022-04-23 16:34      1    踩      回复

tql


用户头像
toyer   2020-11-24 15:14      1    踩      回复

那个请问为什么i = C.size() - 1时 t 一定小于 10?

用户头像
捡到一束光   2020-11-24 15:41      1    踩      回复

比如你拿最大3位数和2位数相乘999*99得到98901,最高位是9小于10,那其他数相乘就更小于10了

用户头像
toyer   2020-11-24 16:01    回复了 捡到一束光 的评论      1    踩      回复

对哦,谢谢大佬了


用户头像
抽象带蓝子   1个月前         踩      回复

tql,感谢大佬


用户头像
云遮月酒亦寒   3个月前         踩      回复

orz


用户头像
阿芙乐尔.   4个月前         踩      回复

顶顶顶!


用户头像
伍玖初号机   5个月前         踩      回复

请问高精度*低精度应该不会有前导零出现吧,去掉应该没什么事吧


用户头像
Hushsss   8个月前         踩      回复

hao


用户头像
三线酒架   8个月前         踩      回复

牛逼牛逼,一看就懂,写的太棒了


用户头像
最低甜度   9个月前         踩      回复

谢谢大佬,高精度乘高精度一下就看明白了 ,orz


用户头像
y_hm   9个月前         踩      回复

大佬的图解太棒了,一下子就理解了,tql,膜拜


用户头像
Whiting   10个月前         踩      回复

# orz


你确定删除吗?

© 2018-2024 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息