高精度算法-大数乘法

问题 E: A × B problem

时间限制: 1 Sec   内存限制: 64 MB
提交: 887   解决: 183
[ 提交][ 状态][ 讨论版]

题目描述

Redraiment碰到了一个难题,需要请你来帮忙:给你两个整数,请你计算A × B。

输入

数据的第一行是整数T(1 ≤ T ≤ 20),代表测试数据的组数。 接着有T组数据,每组数据只有一行,包括两个非负数A和B。 但A和B非常大,Redraiment能保证这些数用long来保存一定会溢出。 但A和B的位数最大不会超过100位。

输出

对应每组测试数据,你都要输出两行: 第一行为:"Case #:", # 代表这是第几组测试数据。 第二行是一个等式:"A * B = Sum", Sum 代表 A × B 的结果。 你要注意这个等式里包含了几个空格。 要求每组数据之后都需要保留一个空行。

样例输入

2
1 2
123456789 987654321

样例输出

Case 1:
1 * 2 = 2
 
Case 2:
123456789 * 987654321 = 121932631112635269

 

解题思路:

模仿大数加法的算法,对进位进行考虑

唯一区别在于大数乘法是先乘后加

大数加法只是加法

 

我的代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 void choose(char q[])//数组倒置函数
 5 {
 6     int i,ll;
 7     char tmp;
 8     ll=strlen(q);
 9     for(i=0;i<ll/2;i++)
10     {
11         tmp=q[i];q[i]=q[ll-i-1];q[ll-i-1]=tmp;
12     }
13 }
14 
15 void fun(char a[],char b[],char c[],int n)
16 {
17     int i,j,jinw=0,x,y,z;
18     int l1,l2,l3;
19     choose(a);
20     choose(b);
21     l1=strlen(a);
22     l2=strlen(b);
23 
24     for(i=0;i<=l1+l2;i++)//对C数组“初始化”,以应对多组输入
25     c[i]=0;
26 
27     for(i=0;i<l2;i++)
28     {
29         for(j=0;j<l1;j++)
30         {
31             x=b[i]-'0';
32             y=a[j]-'0';
33             z=x*y;
34             if(jinw)//如果有进位
35                 z+=jinw;
36             if(z>9)//考虑当前数累加是否会导致下次计算进位
37             {
38                 jinw=z/10;
39                 z%=10;
40             }
41             else
42                 jinw=0;
43 
44             c[i+j]+=z;
45         }
46     }
47     if(jinw)//考虑最后一位是否还有进位
48     {
49         for(i=0;i<l1+l2-1;i++)
50             c[i]+='0';
51         c[l1+l2-1]+=jinw+'0';
52     }
53     else
54     {
55         for(i=0;i<l1+l2-1;i++)
56             c[i]+='0';
57     }
58     for(i=0;i<strlen(c);i++)
59     {
60         if(c[i]>'9')
61             {
62                 c[i]-='0';
63                 jinw=c[i]/10;
64                 c[i]%=10;
65                 c[i]+='0';
66                 c[i+1]+=jinw;
67             }
68     }
69     l3=strlen(c);
70     c[l3]='\0';//为C数组添加终止符
71 
72     printf("Case %d:\n",n);
73     for(i=l1-1;i>=0;i--)
74         printf("%c",a[i]);
75     printf(" * ");
76     for(i=l2-1;i>=0;i--)
77         printf("%c",b[i]);
78     printf(" = ");
79     for(i=strlen(c)-1;i>=0;i--)
80         printf("%c",c[i]);
81     printf("\n\n");
82 }
83 
84 int main()
85 {
86     int n,m;
87     char a[200],b[200],c[2000];
88     while(scanf("%d",&n)!=EOF)
89     {
90         m=n;
91         while(n--)
92         {
93             scanf("%s%s",a,b);
94             fun(a,b,c,m-n);
95         }
96     }
97     return 0;
98 }

 

根据样例输入可得:

但是自测有些小的数相乘则会出现错误,这是为什么呢= = ?

@蚂蚁学姐 求助~!!

转载于:https://www.cnblogs.com/wushuaiyi/p/3463477.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值