话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。
现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。
Input
本题目包含多组测试数据,请处理到文件结束。
每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。
Output
请在一行里面输出输出A+B的值,请输出最简形式。详细要求请见Sample Output。
Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1
Sample Output
4
3.4555434454
2.1
题意:小明啊你以为你换个马甲我就不认识你了嘛!!!
解题思路:
哎呀好气啊。。。
有三种情况:
整数+整数
整数+小数(小数+整数)
小数加小数
处理数据之前判断一下这个数是整数还是小数,分情况处理。
第一个数存在a[]字符串数组里,
第二个数存在b[]字符串数组里。
第一个数的整数部分存在c[]数组,长度为p
第一个数的小数部分存在d[]数组,长度为q
第二个数的整数部分存在e[]数组,长度为r
第二个数的小数部分存在f[]数组,长度为s
(为了方便的解读代码= =)
相加后结果的整数部分存在m[]数组
相加后结果的小数部分存在n[]数组
下面开始模拟:
数据处理:输入一个数,将他分为整数部分和小数部分,如果没有小数部分(即aa.find(“.”)==-1,这个一会要着重说一下= =),则小数部分长度设为1,小数部分就一个数0。
计算:分为整数部分计算和小数部分计算。先进行小数部分计算,方便这种情况:如果有小数部分进位到整数部分则整数部分的个位数+1就行了。
按位计算,n[i]=d[i]+f[i],m[i]=c[i]+e[i]。最重要的就是进位处理了,还有最高一位的情况(在这里我是单独输出最高一位的)。
输出:按顺序输出,先输出整数部分,再输出小数部分。输出小数部分之前先判断一下是否存在小数部分(如果小数部分全为0那就是不存在了)。如果存在还有一种特殊情况,如:12.3458+6.7002=19.0460。最后一个0当然是多余的,怎么处理呢?在这里是先把小数部分n[]数组倒过来判断一下,如果末位有多余的0则小数部分的长度就随之减少,这样输出的时候输到0之前就结束了。详见代码。
这里说一下string容器。
我是想方便找小数点的,可是发现判断找不到的返回值跟书上说的有些出入。
原文如下:
采用find()方法可查找字符串中的第一个字符元素(char,用单引号界定)或者子串(用双引号界定),如果查到,则返回下标值(从0开始计数),如果查不到,则返回4294967295。————曾宗根《ACM程序设计P31》
这个返回值有些特殊,见下:
unsigned int(无符号基本整型) 字节数4 取值范围为0~4294967295(即0~2^32-1)
unsigned long long(无符号双长整型) 字节数8 取值范围0~18446744073709551615(即0~2^64-1)
我分别在同一个编译器上做了两个实验,第一个是在数字中查找小数点的位置,结果找不到都是返回-1,第二是照着书上打的,找不到结果却返回了第二个值18446744073709551615,但是这三个值都是无符号型。(具体-1怎样当做无符号型的不再多说)
万般苦恼。
但终找出两个解决方案:
1,可以像我一样提前做个小实验读取这个值。。
2,将找不到结果的返回值写string::npos
!!!
即if(a.find(“xxx”)==string::npos) printf(“没找着!”\n);
但是对于这道题其实for循环就可以了。。
真的不想再多做一遍。。。
总之,还是自己水平太低了。。。
AC代码:
(去注释去调教过程版)
#include
#include
#include
#include
using namespace std;
string aa,bb;
char a[410],b[410];
int main()
{
int i,j,p,q,r,s,pos1,pos2,l,h;
int c[410],d[410],e[410],f[410],m[410],n[410];
while(~scanf("%s%s",a,b))
{
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
memset(m,0,sizeof(m));
memset(n,0,sizeof(n));
aa=a;
bb=b;
l=strlen(a);
h=strlen(b);
pos1=aa.find(".");
pos2=bb.find(".");
//处理数据
if(pos1==-1)
{
for(i=l-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
q=1;
d[0]=0;
}
else
{
for(i=pos1-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
for(i=pos1+1,q=0;i'0';
}
}
if(pos2==-1)
{
for(i=h-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
s=1;
f[0]=0;
}
else
{
for(i=pos2-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
for(i=pos2+1,s=0;i'0';
}
}
//计算
int max1=(p>r)?p:r;
int max2=(q>s)?q:s;
//小数部分
for(i=max2-1;i>=1;i--)
{
n[i]=d[i]+f[i];
if(n[i]>=10) {n[i]-=10;d[i-1]++;}
}
n[0]=d[0]+f[0];
if(n[0]>=10) {n[0]-=10;c[0]++;}
//整数部分
for(i=0;i1;i++)
{
m[i]=c[i]+e[i];
if(m[i]>=10) {m[i]-=10;c[i+1]++;}
}
m[max1-1]=c[max1-1]+e[max1-1];
//输出结果
//输出整数部分
for(i=max1-1;i>=0;i--)
{
printf("%d",m[i]);
}
//判断有没有小数部分
int flag=0;
for(i=0;iif(n[i]!=0) flag=1;//如果小数部分有值
}
//输出小数部分
if(flag==0) printf("\n");
else
{
printf(".");
for(i=max2-1;i>=0;i--)//处理后缀0!
{
if(n[i]!=0) break;
if(n[i]==0) max2--;
}
for(i=0;iprintf("%d",n[i]);
}
printf("\n");
}
}
return 0;
}
(艰辛的调教过程版。。)
#include
#include
#include
#include
using namespace std;
string aa,bb;
char a[410],b[410];
int main()
{
int i,j,p,q,r,s,pos1,pos2,l,h;
int c[410],d[410],e[410],f[410],m[410],n[410];
while(~scanf("%s%s",a,b))
{
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
memset(f,0,sizeof(f));
memset(m,0,sizeof(m));
memset(n,0,sizeof(n));
aa=a;
bb=b;
l=strlen(a);
h=strlen(b);
pos1=aa.find(".");
pos2=bb.find(".");
//printf("pos1===%d\npos2===%d\n",pos1,pos2);
//if(s.find("a") == string::npos)string::npos通用处理
//处理数据
if(pos1==-1)
{
for(i=l-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
q=1;
d[0]=0;
}
else
{
for(i=pos1-1,p=0;i>=0;i--)
{
c[p++]=a[i]-'0';
}
for(i=pos1+1,q=0;iq++]=a[i]-'0';
}
}
if(pos2==-1)
{
for(i=h-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
s=1;
f[0]=0;
}
else
{
for(i=pos2-1,r=0;i>=0;i--)
{
e[r++]=b[i]-'0';
}
for(i=pos2+1,s=0;is++]=b[i]-'0';
}
}
/*
printf("************\n");
for(i=0;iprintf("%d",c[i]);
printf("\n");
for(i=0;i<q;i++)
printf("%d",d[i]);
printf("\n");
for(i=0;iprintf("%d",e[i]);
printf("\n");
for(i=0;i<s;i++)
printf("%d",f[i]);
printf("\n");
printf("************\n");
*/
//计算
int max1=(p>r)?p:r;
int max2=(q>s)?q:s;
/*
printf("max1===%d\nmax2===%d\n",max1,max2);
printf("************\n");
printf("f[2]===%d\n",f[2]);
printf("d[2]+f[2]===%d\n",d[2]+f[2]);
printf("d[1]+f[1]===%d\n",d[1]+f[1]);
printf("d[0]+f[0]===%d\n",d[0]+f[0]);
*/
//小数部分
for(i=max2-1;i>=1;i--)
{
n[i]=d[i]+f[i];
//printf("n[%d]===%d\n",i,n[i]);
if(n[i]>=10) {n[i]-=10;d[i-1]++;}
}
n[0]=d[0]+f[0];
//printf("n[0]===%d\n",n[0]);
if(n[0]>=10) {n[0]-=10;c[0]++;}
/*
printf("************\n");
printf("************\n");
for(i=0;iprintf("%d",n[i]);
printf("\n");
printf("************\n");
*/
//printf("c[0]===%d\n",c[0]);
//整数部分
for(i=0;i1;i++)
{
m[i]=c[i]+e[i];
//printf("m[%d]===%d\n",i,m[i]);
if(m[i]>=10) {m[i]-=10;c[i+1]++;}
}
m[max1-1]=c[max1-1]+e[max1-1];
//输出结果
//输出整数部分
//if(m[max1])
//printf("c[max1-1]===%d\ne[max1-1]===%d\n",c[max1-1],e[max1-1]);
//printf("m[max1-1]===%d\n",m[max1-1]);
for(i=max1-1;i>=0;i--)
{
printf("%d",m[i]);
}
//判断有没有小数部分
int flag=0;
for(i=0;iif(n[i]!=0) flag=1;//如果小数部分有值
}
//输出小数部分
if(flag==0) printf("\n");
else
{
printf(".");
for(i=max2-1;i>=0;i--)//处理后缀0!
{
if(n[i]!=0) break;
if(n[i]==0) max2--;
}
for(i=0;iprintf("%d",n[i]);
}
printf("\n");
}
}
return 0;
}