大数乘法--------------------------51nod1027

10^1000内的两个大数相乘,10^1000000内的大数相乘是5级算法题,有些难,得用快速傅里叶变换

上一篇讲了大数的阶乘,用的是10000进制,这一篇是大数乘法,也是用10000进制做的。

模拟中国教学的笔算十进制方法(不同于西方国家),进行大数相乘。比大数的阶乘难了一丢丢,因为阶乘是一个大数乘以一个10000以内的数。而大数乘法是两个1000位(本题)的大数相乘,多了个大数的加法运算。

下面的算法不是模拟计算机的乘法(我计算机组成原理学的不好,模拟不了机器)

51nod1027 51nod1028是百万位的大数相乘,嗯,比较难。2017/9/6 AC了,FFT(下面的代码不能解决1028,没有贴出来)

《大数乘法--------------------------51nod1027》

输入两个大非负整数,输出积 (代码后还有分析)

#include <cstdio>
#include <cstring>
const int N = 1010, BASE = 10000;
char a[N], b[N];
int bit[N >> 1], eax[N >> 1], res[N >> 1];
void add(int EAX[], int len, int phase) {
	for (int i = phase, j = 0; j < len; ++j, ++i) {
		res[i] += EAX[j];
		if (res[i] >= BASE) {
			res[i] -= BASE;
			res[i + 1]++;
		}
	}
}
int main()
{
	for (int i = 0; i < 4; ++i) a[i] = b[i] = '0';
	while (~scanf("%s%s", a + 4, b + 4)) {
		memset(bit, 0, sizeof bit);
		memset(res, 0, sizeof res);
		int len_a = strlen(a), len_b = strlen(b), i, len = 0, phase = 0;
		int guard = len_a % 4; if (guard == 0) guard = 4;
		for (i = len_a - 1; i > guard; i -= 4) {
			for (int j = 0, k = i - 3; j < 4; ++j, ++k)
				bit[len] = bit[len] * 10 + a[k] - '0';
			len++;
		}
		guard = len_b % 4; if (guard == 0) guard = 4;
		for (i = len_b - 1; i > guard; i -= 4, ++phase) { //phase 相位移
			int num = 0, c = 0, j;
			for (int j = 0, k = i - 3; j < 4; ++j, ++k) {
				num = num * 10 + b[k] - '0';
			}
			for (j = 0; j < len; ++j) {
				eax[j] = bit[j] * num + c; c = 0;
				if (eax[j] >= BASE) {
					c = eax[j] / BASE;
					eax[j] %= BASE;
				}
			}
			if (c) eax[j++] = c;
			add(eax, j, phase); // res += eax;
		}
		i = (len_a + len_b - 8 >> 2) + ((len_a + len_b - 8) % 4 > 0);
		while (i > 1 && res[i - 1] == 0) --i;
		printf("%d", res[--i]);
		while (i-- > 0) printf("%04d", res[i]);
		puts("");
	}	
	return 0;
}

对上面代码分析:

1、对于两个数(位数分别为len_a, len_b)相乘,要知道,它们的积要么是(lan_a + lan_b)位,要么是(len_a + len_b – 1)位。举个例子:2位数乘4位数。10 * 1000 = 10000(5位数);99 * 9999 = (100 – 1) * (10000 – 1) = 100 0000 – n. (6位数),对吧。

2、为什么我读入大数字符串时没有从下标0或1开始?想一想,为什么?

因为我用的10000进制,每4位数作为一个1w进制的数。但是,乘数的位数不一定能被4整数。

3、note that 结果不要前导0.

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/baisedeqingting/article/details/77622919
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞