博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[置顶] 大整数乘法
阅读量:6832 次
发布时间:2019-06-26

本文共 2234 字,大约阅读时间需要 7 分钟。

问题描述

求两个不超过 200 位的非负整数的积。
输入数据
有两行,每行是一个不超过 200 位的非负整数,没有多余的前导0。
输出要求
一行,即相乘后的结果。结果里不能有多余的前导 0,即如果结果是342,那么就不能
输出为0342。
输入样例
12345678900
98765432100
输出样例
1219326311126352690000

解题思路

在下面的例子程序中,用 unsigned an1[200]和unsigned an2[200]分别存放两个乘数,用

aResult[400]来存放积。计算的中间结果也都存在aResult 中。aResult 长度取400 是因为两个
200 位的数相乘,积最多会有400 位。an1[0], an2[0], aResult[0]都表示个位。
计算的过程基本上和小学生列竖式做乘法相同。为编程方便,并不急于处理进位,而将
进位问题留待最后统一处理。
现以 835×49 为例来说明程序的计算过程。先算835×9。5×9 得到45 个1,3×9 得到27 个10,8×9 得到72 个100。由于不急
于处理进位,所以835×9 算完后,aResult 如下:

图 7-2-1

接下来算4×5。此处4×5 的结果代表20 个10,因此要 aResult[1]+=20,变为:

图 7-2-2

再下来算4×3。此处4×3 的结果代表12 个100,因此要 aResult[2]+= 12,变为:

图 7-2-3

最后算 4×8。此处4×8 的结果代表 32 个1000,因此要 aResult[3]+= 32,变为:

图 7-2-4

乘法过程完毕。接下来从 aResult[0]开始向高位逐位处理进位问题。aResult[0]留下5,
把4 加到aResult[1]上,aResult[1]变为51 后,应留下1,把5 加到aResult[2]上……最终使
得aResult 里的每个元素都是1 位数,结果就算出来了:

图 7-2-5

总结一个规律,即一个数的第i 位和另一个数的第j 位相乘所得的数,一定是要累加到
结果的第i+j 位上。这里i, j 都是从右往左,从0 开始

参考程序:

1. #include <stdio.h>

2. #include <string.h>
3. #define MAX_LEN 200
4. unsigned an1[MAX_LEN+10];
5. unsigned an2[MAX_LEN+10];
6. unsigned aResult[MAX_LEN * 2 + 10];
7. char szLine1[MAX_LEN+10];
8. char szLine2[MAX_LEN+10];
9. int main()
10. {
11. gets( szLine1); //gets 函数读取一行
12. gets( szLine2);

13. int i, j;

14. int nLen1 = strlen( szLine1);
15. memset( an1, 0, sizeof(an1));
16. memset( an2, 0, sizeof(an2));
17. memset( aResult, 0, sizeof(aResult));
18. j = 0;
19. for( i = nLen1 - 1;i >= 0 ; i --)
20. an1[j++] = szLine1[i] - '0';
21. int nLen2 = strlen(szLine2);
22. j = 0;
23. for( i = nLen2 - 1;i >= 0 ; i --)
24. an2[j++] = szLine2[i] - '0';
25.
26. for( i = 0;i < nLen2; i ++ ) { //每一轮都用an1 的一位,去和an2 各位相乘
27. //从an1 的个位开始
28. for( j = 0; j < nLen1; j ++ ) //用选定的an1 的那一位,去乘an2 的各位
29. aResult[i+j] += an2[i]*an1[j]; //两数第i, j 位相乘,累加到结果的第i+j 位
30. }
31. //下面的循环统一处理进位问题
32. for( i = 0; i < MAX_LEN * 2; i ++ ) {
33. if( aResult[i] >= 10 ) {
34. aResult[i+1] += aResult[i] / 10;
35. aResult[i] %= 10;
36. }
37. }
38. //下面输出结果
39. bool bStartOutput = false;

40. for( i = MAX_LEN * 2; i >= 0; i -- )

41. if( bStartOutput)
42. printf("%d", aResult[i]);
43. else if( aResult[i] ) {
44. printf("%d", aResult[i]);
45. bStartOutput = true;
46. }
47. if(! bStartOutput )
48. printf("0");
49. return 0;
50. }

 

你可能感兴趣的文章
linux磁盘管理
查看>>
索骥馆-走向世界之《用美国小孩的方法学英文动词》扫描版[PDF]
查看>>
Android之基于XMPP协议即时通讯软件(三)
查看>>
对SEO网站优化使用技巧的总结
查看>>
yolov3 darknet:parser.c:315: failed
查看>>
网络MSDTC(分布式事务处理协调器)服务配置方法
查看>>
函数嵌套(c++)
查看>>
MySQL线程共享内存参数
查看>>
线上部署链路聚合bonding
查看>>
mysqlsla日志分析工具
查看>>
linux 制作BT种子并获取BT种子信息
查看>>
Building C Projects
查看>>
iOS:XCode 4.2开始Objective-C支持ARC
查看>>
如何解决笔记本键盘的虚拟键盘问题
查看>>
dabo aui editra 三个软件(框架or应用)之间有关系
查看>>
brew使用
查看>>
Swift语言快速入门
查看>>
学LIUNX的常用英语补习
查看>>
单点登录CAS解决方案<一>:纯净CAS-Server
查看>>
linux 下配置mysql主从同步的步骤
查看>>