说明
高精度除法是最后一个高精度运算了,也就是你学完了这一节,以后碰到了要用高精度算法的题都可以做了,好了,其他的我就不多说了。
高精除低精
除法模拟
高精除低精,就是字面意思,一个很大的数除一个很小的数。
下面就先用表格模拟下除法的过程。
1 | 2 | 8 | ||
---|---|---|---|---|
/ | 4 | |||
3 | 2 |
- 我们不可能真的搞一个很大的数去除一个很小的数吧, 这个就有点不现实了,就只能用一个简单的除法去模拟了
- 首先我们是用1 除4 ,我们会发现不够除,我们就需要向前借一位,就变成了12了,现在就是用12 除4 了,刚好能除尽,等于3,之后就是用8除,也是刚好能除尽,等于2.
- 除法你们应该都是会的, 我这里就浅浅的说说,因为我下面就是要用这个过程去模拟除法。
程序模拟
- 如果你是学了,高精度加法,减法,乘法,你会发现,高精度除法会有个与众不同的地方就是不用把输入的字符串进行反转,这是因为除法就是用从最高位开始除的,而其他的运算都是从最低位开始的,这就是不同的之处。
- 但是还是要进行转变成整型,不可能用字符串去做除法吧。
for (int i = 0; i < str1.size(); i ++)
a[i] = str1[str1.szie()-1-i] - '0';
- 这里是第一步,但有个重要点就是要用一个变量承接余数,就看这上面的数123/4,是先用1除吧,但是1除不尽,这里不就余1了嘛,所以就用一个变量来承接它,但是不要忘记了这里是高精除,所以这个余数可能会很大,所以得开long long
long long ans = 0;
- 下面就是真正的模拟除法的过程了。
for (int i = 0; i < str1.size(); i ++) {
c[i] = (ans * 10 + a[i]) / b;
ans = (ans * 10 + a[i]) % b;
}
- 先来看下c[i] = (ans * 10 + a[i]) / b , 就用上面的例子说明,先是1 除,刚开始的没有余数,所以 ans * 10,就没什么用,就只是用a[i], 除,1 除 4 不能除,整除所以就是零,
- 之后就要移到下一位去,但是要把上一次不够除的也加上,但是这个加上不再是简单的加了, 就得再乘以10了,这是跳了一位了,没毛病吧,但是我们还得先求这个余数。
- ans = (ans * 10 + a[i]) % b 这个就是求余数,因为一开始是没有余数的,所以就直接是a[i] 求余,但是如果是进行到,下一步了,就是用12 除了,这是就很有必要写上 ans * 10,不然就是用2 求余,这不就出错了嘛,这一步就是求余的过程。
- 最后也就和高精度加法,减法乘法一样了, 也就是去前导零。
long long lc = 0;
while (l2[lc] == 0 && lc < str.size())
lc += 1;
- 这里你可能会很好奇为什么还要定义一个变量,这是因为除法是从最高位开始除的,就上面的例子一样,1除不尽,得到零,就是在最前面,所以这里就是定义一个变量从头开始判断有没有前导零,如果有前导零就要去掉。
- 最后就是输出了。
for (int i = lc; i < str.size(); i ++)
cout << l2[i];
你可以写下这题(A/B Problem 看下学习的成果。
那我顺便把这题完整的代码说下吧:
#include<iostream>
#include<string>
using namespace std;
const int N = 5010;
int l1[N], l2[N];
long long b;
int main()
{
string str;
cin >> str;
cin >> b;
for (int i = 0; i < str.size(); i ++)
l1[i] = str[i] - '0';
long long rem = 0; // 这个就是记入余数的
for (int i = 0; i < str.size(); i ++){
l2[i] = (rem * 10 + l1[i]) / b;
rem = (rem * 10 + l1[i]) % b;
}
long long lc = 0;
while (l2[lc] == 0 && lc < str.size())
lc += 1;
for (int i = lc; i < str.size(); i ++)
cout << l2[i];
return 0;
}
高精除高精
待更新…