九度OJ 1137

题目描述:

求2个浮点数相加的和
题目中输入输出中出现浮点数都有如下的形式:
P1P2...Pi.Q1Q2...Qj
对于整数部分,P1P2...Pi是一个非负整数
对于小数部分,Qj不等于0

输入:

对于每组案例,第1行是测试数据的组数n,每组测试数据占2行,分别是两个加数。
每组测试数据之间有一个空行,每行数据不超过100个字符

输出:

每组案例是n行,每组测试数据有一行输出是相应的和。
输出保证一定是一个小数部分不为0的浮点数

样例输入:
2
0.111111111111111111111111111111
0.111111111111111111111111111111

10000000.655555555555555555555555555555
1.444444444444444444444444444445
样例输出:
0.222222222222222222222222222222
10000002.1

大整数相加的题目,乍一看只要用字符串保存操作数,然后每位相加,输出结果即可。
但是在实际操作时,却遇到了很多麻烦,很多细节要注意,这里有两大难点。第一,小数点的存在使这个题目有点棘手,每次进位到小数点都要判断一下,跳一位。第二,小数部分和整数部分存在位数不等的情况,这个要先对齐然后再相加,比较麻烦。
针对这两个难点,我的处理方法是,先将操作数A,B的小数点去掉,按整数部分和小数部分最长的那个进行拓展,比如1234.12345+123.345
就可以拓展成123412345+012334500 这样的话,就可以直接相加,最后把小数点添进去(利用小数部分相加,位数是固定的)。最后还要把整数部分小数部分多余的0去掉。这道题花了很长时间才AC

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

int FindDot(string str){
    for(int i=0;i<str.length();i++){
        if(str[i] == '.'){
            return i;
        }
    }
    return -1;
}

int main(){
    int n;
    cin>>n;
    string str1,str2;
    while(n--){
        cin>>str1>>str2;
        int dot1 = FindDot(str1);
        int len1 = str1.length() - dot1 - 1;
        int dot2 = FindDot(str2);
        int len2 = str2.length() - dot2 - 1;
        int dot = max(dot1,dot2);
        int len = max(len1,len2) + dot;
        int opera1[110];
        int opera2[110];
        int result[110];
        int Result[110];
        memset(opera1,0,sizeof(opera1));
        memset(opera2,0,sizeof(opera2));
        memset(result,0,sizeof(result));
        memset(Result,0,sizeof(Result));
        int tmp1 = dot1,tmp2 = dot2;
        for(int i=dot-1;i>=0;i--){      //整数部分
            tmp1 --;
            if(tmp1<0)
                opera1[i] = 0;
            else
                opera1[i] = str1[tmp1] - '0';
            tmp2 --;
            if(tmp2<0)
                opera2[i] = 0;
            else
                opera2[i] = str2[tmp2] - '0';
        }
        for(int i=dot;i<len;i++){    //小数部分
            if(dot1>=str1.length()-1)
                opera1[i] = 0;
            else
                opera1[i] = str1[++dot1] - '0';
            if(dot2>=str2.length()-1){
                 opera2[i] = 0;
            }
            else
                opera2[i] = str2[++dot2] - '0';
        }
        for(int i=len;i>=0;i--){    //相加
            int temp = result[i] + opera1[i-1] + opera2[i-1];
            result[i] = temp % 10;
            result[--i] = temp / 10;
            i++;
        }
        int j = 0;
        int k = len;
        while(j<max(len1,len2)){
            Result[k+1] = result[k];    //Result保存最终结果,给小数点腾出一位
            k--;
            j++;
        }
        Result[k+1] = -1;     //小数点位置设置为-1
        Result[k] = result[k];   //整数部分至少留一位
        j = 0;
        while(result[j]==0 && j<k){    //整数部分的前面多余的0去掉
            j++;
        }
        for(int i=j;i<k;i++){
            Result[i] = result[i];   //整数部分保持不动
        }
        k = len+1;
        while(Result[k]==0){    //小数点后面多余的0去掉
             k--;
        }
        for(int i=j;i<=k;i++){
            if(Result[i] == -1)
                cout<<".";
            else
            cout<<Result[i];
        }
        cout<<endl;
    }
    return 0;
}



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值