题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1753
题目:
|
分析:
大数计算问题。我的方法是将之存入数组。因为A、B均为正小数。所以又分有整数小数部分,可通过strstr()函数先找到小数点位置,分开整数小数部分。因为小数位数不同,不便运算,所以将数组元素先初始化为0。存数时,先将整数部分倒序存储。因为这样便于解决运算中最终的进位问题;小数部分直接按序存,最终进位加至整数部分。计算思路模拟手算,一位一位算。
另外注意考虑了小数情况,还要考虑到只是整数相加的情况。输出时也注意何时输出小数点等,还有小数中末尾的0要去掉。可以在输出之前先判断小数部分的位数,从后往前,遇到非零则跳出,从而找到小数部分的最终长度。
总体步骤:
1.初始化数组(全设为0);
2.存数:找到小数点位置,存储A、B整数部分小数部分;
3.计算小数:先小数部分从后往前一位位加,记录小数位数(末尾多余的0不计,记录化简后的位数);
4.计算整数:再整数部分加和;
5.输出结果:最终输出整数部分,有小数部分则输出;
代码:
#include <stdio.h>
#include <string.h>
int main()
{
char a[403], b[403];
int a1[403],a2[403],b1[403],b2[403];
int pa,pb,lena,lenb,lena1,lena2;
int i;
while(~scanf("%s%s",a,b))
{
memset(a1,0,sizeof(a1));
memset(a2,0,sizeof(a2));
memset(b1,0,sizeof(b1));
memset(b2,0,sizeof(b2));
lena=strlen(a);
lenb=strlen(b);
if (strstr(a,".")) pa = strstr(a,".")-a;//找到小数点位置下标
else pa = lena;
if (strstr(b,"."))pb = strstr(b,".")-b;
else pb = lenb;
for (i=0; i<pa; i++)
a1[pa-1-i] = a[i]-'0';
for (i=0; i<pb; i++)
b1[pb-1-i] = b[i]-'0';
//将a、b的整数部分存入a1、b1(个位为第0个数组元素)
for (i=0; i<lena-pa-1; i++)
a2[i] = a[pa+i+1]-'0';
for (i=0; i<lenb-pb-1; i++)
b2[i] = b[pb+i+1]-'0';
//将a、b的小数部分存入a2、b2
for (i=400; i>0; i--)//小数相加,存在数组a2中
{
a2[i] += b2[i];
a2[i-1] = a2[i-1] + a2[i]/10;//将进位加至前一位
a2[i] %= 10;
}
a2[i] += b2[i];//计算小数点后一位的加和
a1[0] = a1[0] + a2[i]/10;//将进位加至个位
a2[i] %= 10;
lena2 = -1;//记录小数位数,位数为lena2+1
for (i=400; i >=0; i--)
{
if (a2[i]){ lena2 = i+1;break;}
}
lena1 = pa>pb ? pa : pb;
for (i=0; i<lena1; i++)//整数相加
{
a1[i] += b1[i];
a1[i+1] = a1[i+1] + a1[i]/10;
a1[i] %= 10;
}
//printf("lena1=%d\n",lena1);
if (a1[lena1])printf("%d",a1[lena1]);//输出整数进位
for (i=lena1-1; i>=0;i--)//输出整数
//因为AB均正小数,所以整数位数只会多或不变,不会少
{
printf("%d",a1[i]);
}
if (lena2 != -1)
{
printf(".");
for (i=0; i<lena2; i++)
{
printf("%d",a2[i]);
}
}
printf("\n");
}
return 0;
}
据说java的写法要比这C的简单很多,等以后研究学习到了,再来更新java的代码。