高精度乘法中竖式错位问题的分析与总结

题目描述

给出两个非负整数,求它们的乘积。

输入格式

输入共两行,每行一个非负整数。

输出格式

输出一个非负整数表示乘积。

输入输出样例

输入 #1

1 
2

输出 #1

2

说明/提示

每个非负整数不超过 10^2000。


代码如下:

#include <iostream>
#include <cmath>
using namespace std;
int a[10001], b[10001], c[10003], len1, len2;

int main() {
	string A, B;
	cin >> A >> B;
	len1 = A.length();
	len2 = B.length();
	for (int i = 1, j = len1 - 1; j >= 0; i++, j--)
		a[i] = A[j] - '0';
	for (int i = 1, j = len2 - 1; j >= 0; i++, j--)
		b[i] = B[j] - '0';
	for (int i = 1; i <= len2; i++)
		for (int j = 1; j <= len1; j++)
			c[i+j-1] += a[j] * b[i];		//先进行乘法运算,计算进位放在代码后半部分
	int len = len1 + len2;
	for (int i = 1; i < len; i++)
		if (c[i] >= 10) {
			c[i+1] += c[i] / 10;
			c[i] %= 10;
		}
	while (!c[len])							//处理答案的前导零
		len--;
	for (int i = max(1, len); i >= 1; i--)	//逆序输出即可
		cout << c[i];
	return 0;
}

面对高精度乘法时,主要难点不在于较大数字的读入,较大数字的读入已经在高精度加法中解决掉了。解决方法为用string变量或者字符数组以字符串的形式逐位存放这个数字,再用循环遍历这个字符串,将其每一位数字逆向存储在新建的整型数组中(注意要开三个整型数组,一个用来存放答案,另外两个用来存放输入的数字)。

至于为什么要逆向存储,是为了便于对加法或者乘法的过程进行模拟。

高精度乘法真正的难点,在于乘法过程中的中间数字错位相加的处理过程。这里的模拟过程如果仿照高精度加法逐步逐步写相加的过程并处理进位,思维上容易混乱,整体代码也显得比较冗杂。因此这里提供一种先计算答案每一位的数字后再进行进位处理的方法。


首先我们来看一下一下数字的乘法竖式:


 不难发现,在错位相加的过程中,得到的结果每一位的下标c的数字与竖式的中间结果的下标a、b数字有一定关系。倘若我们设a的下标为i,b的下标为j,c的下标为t。不难总结出来c的下标与i、j的关系是t = i + j - 1 。再来重新分析一下我们计算乘法竖式的过程,可以发现c(i + j - 1) = a(i) * b(j)都是对应的。所以我们可以先将乘法结果中每一位c(i + j - 1)先行计算出来,不进行进位处理,到最后所有的c(i + j - 1)都计算完毕之后,统一由低位到高位进行进位处理,从而得到最终的结果。得到结果之后,就是要注意输出的过程中需要先将结果的前导零给删除掉。


高精度乘法仍然属于模拟的范畴,在处理此类模拟问题时需要我们善于分析问题和发现问题的核心解决点。

以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YUKIPEDIA~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值