ZCMU 4944: 字符串处理

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;
    }
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值