百练_2980大整数乘法(大数相乘)

描述

求两个不超过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 如下:

               《百练_2980大整数乘法(大数相乘)》

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

               《百练_2980大整数乘法(大数相乘)》

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

             《百练_2980大整数乘法(大数相乘)》

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

              《百练_2980大整数乘法(大数相乘)》

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

              《百练_2980大整数乘法(大数相乘)》

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

 红色表示数位下表i,j:                 

                    8(2)     3(1)      5(0)

              *             4(1)      9(0)

         —————————————————–

                  72(2+0)     27(0+1)    45(0)

         32(2+1)    12(1+1)     20(1+0

         —————————————————–  

         32(3)       84(2)        47(1)       45(0)

         ——————————————————-

         32(3)       84(2)       47+4(1)      5(0)

         ——————————————————- 

         32(3)       84+5(2)       1(1)        5(0)

         ——————————————————-

         32+8(3)      9(2)         1(1)        5(0)

         ——————————————————-

         40(3)        9(2)        1(1)        5(0)         =40915


代码实现:

#include<stdio.h>
#include<string.h>
int main()
{
	int i,j,t,str1,str2,k=0;        //k最为bool值判断c3数值是否为0 
	int  a1[255],a2[255],a3[400];     
	char c1[255],c2[255],c3[400];     //用字符方式存储两个大数的数值
    
	for(i=0;i<255;i++)
	{
		a1[i]=0;               //把int数组内所有数内置为0 
		a2[i]=0;
		
	}
	for(i=0;i<400;i++)
	a3[i]=0;

gets(c1);
gets(c2);                     //用char类型c1,c2存储大数的值 
	 
    str1=strlen(c1);          //用str1表示读入大数的长度 
	str2=strlen(c2);
	
	
	j=0;
	for(i=str1-1;i>=0;i--)   //将大数c1从char类型转换为int类型 
	a1[j++]=c1[i]-'0';
	
	j=0;
	for(i=str2-1;i>=0;i--)   //将大数c2从char类型转换为int类型 
	a2[j++]=c2[i]-'0';


    for(i=0;i<str2;i++)          //各位数上相乘
    {
    	for(j=0;j<str1;j++)    
		{
			a3[i+j]+=a2[i]*a1[j];
		} 
	} 
    
    for(i=0;i<400;i++)        //对各个位数上的数进位相加 
    {
        if(a3[i]>=10)  
		{
		a3[i+1]+=(a3[i]/10);
		a3[i]%=10;
		}
    }
    
   
	for(i=399;i>=0;i--)
	{

	if(a3[i]!=0)   k=1;          //去掉前置0 
	if(k==1) printf("%d",a3[i]);
	}
	if(k==0) printf("0");   //当得到c3为0时候输出数字0 
	printf("\n");
	
	return 0;
	
} 

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