【题目】
4944: 字符串处理
Time Limit: 1 Sec Memory Limit: 32 MB
Submit: 108 Solved: 45
[Submit][Status][Web Board]
Description
读入两个字符串,字符串除了数字还可能包括 '—'、'E'、'e'、'.',相加之后输出结果,如果是浮点型,要求用科学计数法表示(最多包含10个有效数字)。
Input
输入包含多组测试数据。
每组输入占两行,每行一个字符串,测试数据保证字符串的构成严格按照题目中的描述。
Output
输出两个数字相加的结果,每组输出占一行。
Sample Input
34.56
2.45e2
Sample Output
2.7956e2
【题意】
两数求和,若为浮点数则以科学计数法形式输出。
【思路】
以字符串形式存入,预处理两个字符串将e前后边的数值分离,并记录两数小数点后的位数和e后边相乘的位数相抵的结果,将两数化成原始形式扩大相同倍数使得去掉小数点并相加,如果是0或者整型直接输出,否则以科学计数法输出。
【代码】
#include<bits/stdc++.h>
using namespace std;
int flag,c;
long long solve(char *str,int *a)
{
flag=0; //记录正负
c=0; *a=0;
long long s=0; int b;
for(int i=0;str[i];i++)
{
if(str[i]=='-') flag=1;
else if(str[i]=='.') c=1; //存在小数点,c由0->1
else if(str[i]=='e'||str[i]=='E')
{
sscanf(str+i+1,"%d",&b); //b中存储e后边的数值
*a+=b; //小数点后的位数和e后边相乘的位数相抵
break;
}
else
{
s=s*10+str[i]-'0'; //e前边的字符一步步转数值
*a-=c; //记录小数点后的位数
}
}
if(flag) s=-s;
return s; //返回e前边的数值
}
int main()
{
char str1[50],str2[50];
long long s,s1,s2,ans;
int a1,a2,a,w,flag;
while(~scanf("%s%s",str1,str2))
{
//预处理两个字符串并得到相应的a(见上边的注释)
s1=solve(str1,&a1);
s2=solve(str2,&a2);
//把e换算回来并同时扩大相同倍数
if(a1<a2)
{
for(;a1<a2;a2--) s2*=10;
}
else if(a1>a2)
{
for(;a1>a2;a1--) s1*=10;
}
a=a1; s=s1+s2;
if(!s) //和为0直接输出0并跳出循环
{
printf("0\n");
continue;
}
while(a<0&&s%10==0)
{
s/=10; a++;
}
if(a>=0) //非浮点型
{
printf("%lld",s);
for(int i=0;i<a;i++) printf("0");
puts(""); continue;
}
flag=0; //flag记录求和结果的正负
if(s<0)
{
s=-s; flag=1;
}
ans=1,w=0;
while(ans<=s)
{
ans*=10; w++;
}
if(ans>1)
{
ans/=10; w--;
}
if(flag) printf("-"); //负数输出'-'
printf("%lld",s/ans); //输出小数点前边的数值
if(ans>1) printf(".%lld",s%ans); //输出小数点后边的数值
printf("e%d\n",a+w); //输出e后边的数值
}
return 0;
}