4944: 字符串处理
时间限制: 1 Sec 内存限制: 32 MB
提交: 49 解决: 13
[提交][状态][讨论版]
题目描述
读入两个字符串,字符串除了数字还可能包括 '—'、'E'、'e'、'.',相加之后输出结果,如果是浮点型,要求用科学计数法表示(最多包含10个有效数字)。
输入
输入包含多组测试数据。
每组输入占两行,每行一个字符串,测试数据保证字符串的构成严格按照题目中的描述。
输出
输出两个数字相加的结果,每组输出占一行。
样例输入
34.56 2.45e2
样例输出
2.7956e2
回归zcmu的第一天 稍微看了一点网上的代码然后自己理一条思路出来吧 两段字符串 为了防止后面写乱掉 最好还是定义一个结构体包装一下,结构体里包含要输入的字符串以及有没有小数点dian,如果存在科学计数法 则使用enumber存储e后面位数,f来标记是否为负数,ans将输入的字符串变成一个long long的整数(不一定与输入的数字相等,a来表示10的a次方,也就是说ans×10^a才是输入的数字)
那么前期的准备就完成了
然后做一个change函数(因为两个字符串转换成long long 的过程是一样的 因此用函数简化)
处理完后就开始将两个数字乘上对应的相对次幂然后相加(为什么是相对次幂for
(;s1.a<s2.a;s2.a--),如果是绝对次幂 long long也不一定能存储
)
相加后先开始处理特殊情况(起初脑洞不够大 死了两次)
首先肯定是0的时候 直接输出0;
另外如果相加后是整数且处理过后a是正的,那么仍然直接输出,然后再输出a个0
然后如果s小于0 还是先做上标记 再最后判断输出负号
最后处理科学计数法的时候走了一段弯路 因此代码可能有点乱(一直在想数字大于10位,是不是该四舍五入的问题,想的有点多)
科学计数法的表示 无非就是先得到s的位数 然后整除 位数-1 保留第一位,再输出小数点 然后取余保留后续数字(很坑爹的事情!!!如果这个数字只有一位有效数字,比如0.2,那就没有小数点以及后续的数字!!!) 最后输出e以及位数。
#include<bits/stdc++.h>
using namespace std;
typedef struct{
char s[110];
long long enumber,dian,f,a,ans;
}strings;
void change(strings &s){
int f=0;
s.a=s.dian=s.enumber=s.f=s.ans=0;
for(int i=0;i<strlen(s.s);i++){
if(s.s[i]=='-')
s.f=1;
else if(s.s[i]=='.')
s.dian=1;
else if(s.s[i]=='e'||s.s[i]=='E'){
for(i+=1;i<strlen(s.s);i++){
if(s.s[i]=='-'){
f++;
continue;
}
s.enumber=s.enumber*10+s.s[i]-'0';
}
if(f)s.enumber*=-1;
s.a+=s.enumber;
break;
}
else {
s.ans=s.ans*10+s.s[i]-'0';
s.a-=s.dian;
}
}
if(s.f)
s.ans*=-1;
}
int main(){
strings s1,s2;
while(cin>>s1.s>>s2.s){
change(s1);
change(s2);
if(s1.a<s2.a)
for(;s1.a<s2.a;s2.a--)
s2.ans*=10;
else
for(;s1.a>s2.a;s1.a--)
s1.ans*=10;
long long a=s1.a,s=s1.ans+s2.ans,wei,x,sflag=0;
if(!s){
cout<<"0"<<endl;
continue;
}
while(a<0&&s%10==0){
s/=10;
a++;
}
if(a>=0){
cout<<s;
while(a--)cout<<"0";
puts("");
continue;
}
if(s<0){
s*=-1;
sflag++;
}
for(x=s,wei=0;x>0;x/=10,wei++);
if(wei+a>10){
x=s;
int aa=pow(10,(wei+a-10));
x%=aa;
aa/=10;
x/=aa;
}
if(sflag)cout<<"-";
long long aa=pow(10,wei)/10;
cout<<s/aa;
if(aa>1)cout<<"."<<s%aa;
cout<<"e"<<wei-1+a<<endl;
}
}