Description
FJ asks that you do this yourself; don't use a special library function for the multiplication.
Input
Output
Sample Input
11111111111111 1111111111
Sample Output
12345679011110987654321
题目大意:
输入两行,每行一个整数,计算两整数的积。(注意前导零的情况)
解题思路:
高精度的乘法,将两个或多个数以字符串的形式储存在数组中,然后将字符串数组翻转并转化为对应的整形数组,然后用一个数组的每一位去乘另一数组的每一位,累加每一位,最后做进位操作,倒着输出数组即可。
举例说明:1678278312397215与719290058710108相乘
第一步:字符串数组储存
字符数组: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;
}