高精度加法和乘法
加法(只支持自然数的大整数相加)
1.通过模拟加法算式,从右往左依次累加,如果两个不一样长,要在短的前面用0补上。
2.取余保留,除10进位,注意最后一位如果有进位要把进位加上去。
乘法(只支持自然数的大整数相乘)
1. 通过模拟乘法算式,从右往左数的话,s1[i] * s2[j] 贡献给了ans[i+j]。
2.所以为了方便从右往左数, 先把s1,s2翻转,且乘法后的结果最多有 len1+len2位。
3.因为s1[i] * s2[j] 和s1[j] * s2[i]都会贡献给ans[i+j],所以要写两层for循环。
4.贡献值 = 第一次贡献值 + 第二次贡献值,然后取余保留,除10进位。
5.最后得到结果,要找到非0的首位,并且要反过来,也要判断结果为0的时候,返回”0″。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
string add(string s1, string s2) {//模拟加法算式,从右往左加(只支持自然数相加) int len1 = s1.length(), len2 = s2.length(); if (len1 < len2) {//位数不够用0补 string t(len2 - len1, '0'); s1 = t + s1; } else if (len2 < len1) { string t(len1 - len2, '0'); s2 = t + s2; } string ans = s1; int car = 0; for (int i = s1.length() - 1; i >= 0; i--) { ans[i] = (s1[i] - '0' + s2[i] - '0' + car) % 10 + '0'; car = (s1[i] - '0' + s2[i] - '0' + car) / 10; } if (car) ans = (char) (car + '0') + ans;//多出一位进位要加上 return ans; } string mul(string s1, string s2) {//(只支持自然数相乘) vector<int> v(s1.length() + s2.length(), 0); reverse(s1.begin(), s1.end());//翻转便于计算,反转后从右往左,依次为个位、十位... reverse(s2.begin(), s2.end()); for (int i = 0; i < s1.length(); i++) { for (int j = 0; j < s2.length(); j++) { int t = (s1[i] - '0') * (s2[j] - '0') + v[i + j];// v[i + j] = t % 10;//取余保留 v[i + j + 1] += t / 10;//除10进位 } } int i; for (i = v.size() - 1; v[i] == 0; i--);//取非0首位作为第一位 string ans(i + 1, '0'); for (int j = 0; j <= i; j++)//把结果再次反过来保存即可 ans[j] = v[i - j] + '0'; if (ans == "") ans = "0";//如果不存在非0首位,则答案为 "0" return ans; } |