高精度 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图解
C数组的空间其实可以开成A.size()+B.size()就完全足够了,因为A*B的最大长度就是二者的长度之和。
合理的,不可能超过二者长度之和
太清楚了吧
那个图
大佬 高精度 X 低精度
while (t) { // 处理最后剩余的 t
C.push_back(t % 10);
t /= 10;
}
是不是等价于 if(t) C.push_back(t); 写成这个也可以吧
和我想得一样,但是我这样做结果的最高位就是出不来,不知道出啥问题了
不对,应该是if(!t) C.push_back(t);
在这题应该是等价的,但是如果需要用到这个结果运算,就会出错,比如最后的 t 是 大于10的,你vector中存储的就是大于10的数,如果同时进行其他高精度操作时,可能会溢出。做这题,你就理解了 https://www.luogu.com.cn/problem/P1009
不等价,最后的t可能很大,但每次只能取一位,所以要用while
这道题是不是高精度乘以低精度函数和高精度函数相加然后迭代就可以写出来呢
不等价!! t很有可能超过1位,然后需要不停插入,要用while
大数×大数中是不是忘记把t中剩下的位给进完了啊qwq
114514×1919810这样子就会错掉
###
tql
高*低
乘法只有b=0才需要高位弹出,所以mul开头直接加一个判断返回0也可以
if(!b)
{
C.push_back(0);
return C;
}
# 直接收藏!!!
## hhhhh
图解很清楚
for (int i = 0; i < A.size(); i ++)这句如果是i<A.size()||t,是不是不用处理剩下的t了
是的,这样写就好
加个判断,防止数组下标越界
tql
那个请问为什么i = C.size() - 1时 t 一定小于 10?
比如你拿最大3位数和2位数相乘999*99得到98901,最高位是9小于10,那其他数相乘就更小于10了
对哦,谢谢大佬了
各位大佬,提示 auto 那里报错提示没有定义是什么原因啊
tql,感谢大佬
orz
顶顶顶!
请问高精度*低精度应该不会有前导零出现吧,去掉应该没什么事吧
0*10000包有的啊
hao
牛逼牛逼,一看就懂,写的太棒了
谢谢大佬,高精度乘高精度一下就看明白了 ,orz
大佬的图解太棒了,一下子就理解了,tql,膜拜