高精度加减乘除
考虑四种情形
A + B
A - B
A * a
A / a
大整数的存储
一般个位存在下标为0的位置,最高位存在下标最大的位置,方便进位
1 string n = "123456"; 2 vector<int> p = {6, 5, 4, 3, 2, 1};
大整数的加法
假设Ai, Bi都存在,c = Ai + Bi + c,c为进位
假设Ai存在,Bi不存在,则 c = Ai +c
假设Ai不存在,Bi存在,则 c = Bi + c
该位为 c % 10,进位为 c / 10;
对于边界,即最低位和最高位,需要处理进位
最低位相加时,进位肯定为0,在循环外声明即可
最高位相加时,可能进位,需要在循环外判断进位是否为1
1 vector<int> add(vector<int> &a, vector<int> &b) 2 { 3 int c = 0; 4 vector<int> res; 5 for(int i = 0; i < a.size() || i < b.size(); i++) 6 { 7 if(i < a.size()) c += a[i]; 8 if(i < b.size()) c += b[i]; 9 res.push_back(c % 10); 10 c /= 10; 11 } 12 if(c) res.push_back(res); 13 14 return res; 15 }
大整数的减法
在做减法时,需要判断输入的两个数字大小,函数执行得是大数A减小数B
首先被减数先减去借位,c = A[i] - c, c为借位
然后判断Bi是否存在,如果存在,则 c -= B[i]
该位为 (c + 10) % 10,c + 10是为了避免负数,如果c为负数,则借位c = 1,否则为0
最后需要将最高位的0去掉,比如000123,需要返回的是123
1 vector<int> sub(vector<int> &a, vector<int> &b) 2 { 3 int c = 0; 4 vector<int> res; 5 6 for(int i = 0; i < a.size(); i++) 7 { 8 c = a[i] - c; 9 if(i < b.size()) c -= b[i]; 10 res.push_back((c + 10) % 10); 11 if(c < 0) c = 1; 12 else c = 0; 13 } 14 while(res.size() > 1 && res.back() == 0) res.pop_back(); 15 return res; 16 }
大整数乘法
考虑大整数A乘以较小的数B
模拟大整数每一位乘以B,即c = A[i] * B + c,c为进位
该位为 c % 10,进位为c % 10
对于边界,即最低位和最高位,需要处理进位
最低位相乘时,进位为0,在循环外声明即可
最高位相乘时,可能进位,需要在循环外判断进位是否不为0,如果不为0,则将进位压入
1 vector<int> mul(vector<int> &a, int b) 2 { 3 int c = 0; 4 vector<int> res; 5 for(int i = 0; i < a.size(); i++) 6 { 7 c += a[i] * b; 8 res.push_back(c % 10); 9 c /= 10; 10 } 11 if(c) res.push_back(c); 12 return res; 13 }
大整数除法
考虑大整数A除以较小的数B
模拟大整数每一位除以B,不同上述情况,除法必须从最高位开始
该位为 (r * 10 + A[i]) / 10,余数r = (r * 10 + A[i]) % 10, r 为余数
对于边界,即最高位,需要处理余数
最高位相除时,余数为0,在循环外声明即可
最后需要将最高位的0去掉,比如000123,需要返回的是123
1 vector<int> div(vector<int> &a, int b, int &r) 2 { 3 vector<int> res; 4 for(int i = a.size()-1; i >= 0; i--) 5 { 6 r = r*10 + a[i]; 7 res.push_back(r / b); 8 r %= b; 9 } 10 reverse(res.begin(), res.end()); 11 while(res.size() > 1 && res.back() == 0) res.pop_back(); 12 return res; 13 }