您的位置:首页 > 其它

Bull Math(高精度——乘法)

2014-07-31 11:55 369 查看
Description

Bulls are so much better at math than the cows. They can multiply huge integers together and get perfectly precise answers ... or so they say. Farmer John wonders if their answers are correct. Help him check the bulls' answers. Read in two positive integers
(no more than 40 digits each) and compute their product. Output it as a normal number (with no extra leading zeros).

FJ asks that you do this yourself; don't use a special library function for the multiplication.

Input

* Lines 1..2: Each line contains a single decimal number.

Output

* Line 1: The exact product of the two input lines

Sample Input

11111111111111
1111111111


Sample Output

12345679011110987654321


题目大意:

输入两行,每行一个整数,计算两整数的积。(注意前导零的情况)

解题思路:

高精度的乘法,将两个或多个数以字符串的形式储存在数组中,然后将字符串数组翻转并转化为对应的整形数组,然后用一个数组的每一位去乘另一数组的每一位,累加每一位,最后做进位操作,倒着输出数组即可。

举例说明:1678278312397215719290058710108相乘

第一步:字符串数组储存

字符数组:s1[ ]:

i 0 1 2 3 4 5
6 7 8 9 10 11 12 13 14
15

s1[ ] 1 6 7 8 2 7 8 3 1
2 3 9 7 2 1 5


s2[ ]:

j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

s2[ ] 7 1 9 2 9 0 0 5 8 7 1 0 1 0 8

第二步:转化为整形数组并翻转数组(注意去除前导0)

整形数组:a1[ ]:

i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

a1[ ] 5 1 2 7 9 3 2 1 3 8 7 2 8 7 6 1

a2[ ]:

j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

a2[ ] 8 0 1 0 1 7 8 5 0 0 9 2 9 1 7

第三步:计算每一位的乘积并累加

i=0,j从0到最大(在这里是14)

计算每一位的乘积:num[i+j]=a1[i]*a2[j]

k=i+j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

num[ ] 40 0 5 0 5 35 40 25 0 0
45 10 45 5 35

累加每一位的和:sum[k]=sum[k]+num[k]

k 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

num[ ]
40 0 5 0 5 35 40 25 0 0 45 10 45 5 35

旧sum[ ] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

新sum[ ] 40
0 5 0 5 35 40 25 0 0 45 10 45 5 35


i=1,j从0到最大

计算每一位的乘积:num[i+j]=a1[i]*a2[j]

k=i+j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

num[ ] 8
0 1 0 1 7 8 5 0 0 9 2 9 1 7


累加每一位的和:sum[k]=sum[k]+num[k]

k 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

num[ ] 8
0 1 0 1 7 8 5 0 0 9 2 9 1 7


旧sum[ ] 40 0 5 0 5 35 40 25 0 0 45 10 45 5 35

新sum[ ] 48 0 6 0 6 42 48
30 0 0 54 12 54 6 42


…… …… …… ……

…… …… …… ……

i最大(这里是15),j从0到最大

计算每一位的乘积:num[i+j]=a1[i]*a2[j]

k=i+j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

num[ ] 8 0 1 0 1 7 8 5 0 0 9 2 9 1 7

累加每一位的和:sum[k]=sum[k]+num[k]

k 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ……

num[ ] 8
0 1 0 1 7 8 5 0 0 9 2 9 1 7 ……


旧sum[ ] …… …… …… …… ……

新sum[ ] …… …… …… ……
……

第四步:进位操作,将数组的每一位化为小于10的整数

i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

sum 40 8 21 57 79 67 74 65 105 197 234 127 177 186 297 262 250 213 242 249 211 152 173 160 191 106 119 64 43 7 0

sum 0 2 2 9 4 5 1 3 2 8 4 2 2 5 7 3 9 0 6 5 8 5 0 9 8 6 1 7 0 2 1

第五步:倒着输出数组sum即可。

sum:1207168905856093752248231549220

代码如下:

#include<stdio.h>
#include<string.h>
int main()
{
/*num:记录进位的数值;sum数组:开始时储存各个位的和,后来储存进位后各个位的数字;
sum1数组记录将字符str1转换的整数;sum2数组记录将字符str2转换的整数;*/
int i,j,k,n,p,q,num,sum[90]={0},sum1[45],sum2[45];
char str1[45],str2[45];
//对字符串1的操作
scanf("%s",str1);
for(i=0;str1[i]=='0';i++);//去除前导0
n=strlen(str1);//测量字符串1的长度
for(j=n-1,k=0;j>=i;j--,k++)//将字符串的各个位的字符转化为数字,循环次数只需n-i次
sum1[k]=str1[j]-'0';
p=k;//记录整数1的位数
//对字符串2的操作
scanf("%s",str2);
for(i=0;str2[i]=='0';i++);//去除前导0
n=strlen(str2);//测量字符串2的长度
for(j=n-1,k=0;j>=i;j--,k++)//将字符串的各个位的字符转化为数字,循环次数只需n-i次
sum2[k]=str2[j]-'0';
q=k;//记录整数2的位数
//循环,将两整数的任意一位相乘,并累加相应位上的和,此时的和未进行进位操作
for(i=0;i<p;i++)
{
for(j=0;j<q;j++)
{
sum[i+j]=sum[i+j]+sum1[i]*sum2[j];
}
}
//对sum数组的每一位进行进位操作,得到两数相乘的积的各个位的数字
for(i=0;i<p+q;i++)
{
if(sum[i]>9)
{
num=sum[i]/10;
sum[i]=sum[i]%10;
sum[i+1]=sum[i+1]+num;
}
}
//从sum数组的右端开始找,两数相乘结果的最高位
for(i=p+q;sum[i]==0;i--);
//倒着输出sum数组即是两数相乘的积
for(j=i;j>=0;j--)
printf("%d",sum[j]);
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: