九度[1137]-浮点数加法

九度[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

解题思路:
大整数加法;字符串操作;
其实这两个知识点总是一起出现,没什么算法,就是复杂,切记要耐心。

AC代码:

#include <cstdio>
#include <cstring>
const int maxn = 110;
int n;
char input[maxn];
struct number{
    int a[maxn];
    int b[maxn];
    int aSize;
    int bSize;
}num[2];;

void init(){
    for (int i = 0; i < 2; i++){
        for (int j = 0; j < maxn; j++){
            num[i].a[j] = num[i].b[j] = 0;
        }
        num[i].aSize = num[i].bSize = 0;
    }
}

void print(number node){
    for (int i = node.aSize-1; i >= 0; i--){
        printf("%d", node.a[i]);
    }
    printf(".");
    for (int i = 0; i < node.bSize; i++){
        printf("%d", node.b[i]);
    }
    printf("\n");
}

number added(number x, number y){
    number m;
    // init
    for (int i = 0; i < maxn; i++){
        m.a[i] = m.b[i] = 0;
    }
    m.aSize = m.bSize = 1;
    bool flag = false; // 标记小数部分加法是否有进位
    //考虑到进位,先计算小数部分
    int indexB = x.bSize>y.bSize ? x.bSize : y.bSize;
    for (int i = indexB - 1; i >= 0; i--){
        m.b[i] = x.b[i] + y.b[i] + m.b[i];
        if (m.b[i] >= 10){
            m.b[i] %= 10;
            if (i > 0) m.b[i - 1]++;
            else flag = true;
        }
    }
    // 小数部分相加,位数不会变化,所以从end-1开始寻找最后一位不为0的数字
    for (int i = indexB - 1; i >= 0; i--){
        if (m.b[i] != 0){
            m.bSize = i + 1;
            break;
        }
    }
    // 计算整数部分
    int indexA = x.aSize>y.aSize ? x.aSize : y.aSize;
    // 小数计算的进位
    if (flag) m.a[0] += 1;
    for (int i = 0; i < indexA; i++){
        m.a[i] = x.a[i] + y.a[i] + m.a[i];
        if (m.a[i] >= 10){
            m.a[i] %= 10;
            m.a[i + 1]++;
        }
    }
    // 整数部分相加,位数可能会变化,所以从indexA+1开始寻找第一位不为0的数字
    for (int i = indexA + 1; i >= 0; i--){
        if (m.a[i] != 0){
            m.aSize = i + 1;
            break;
        }
    }
    return m;
}

int main(){
    freopen("C:\\Users\\Administrator\\Desktop\\test.txt", "r", stdin);
    while (scanf("%d", &n) != EOF){
        while (n--){
            init();
            for (int i = 0; i < 2; i++){
                scanf("%s", input);
                int len = strlen(input), index = 0, aSize = 0, bSize = 0;
                for (int j = 0; j < len; j++){
                    if (input[j] == '.') {
                        index = j;
                        break;
                    }
                }
                // 整数部分倒序存储;小数部分正向存储,后面补0
                for (int j = index-1; j >= 0; j--){
                    num[i].a[aSize++] = input[j]-'0';
                }
                for (int j = index + 1; j < len; j++){
                    num[i].b[bSize++] = input[j] - '0';
                }
                num[i].aSize = aSize;
                num[i].bSize = bSize;
            }
            print(added(num[0], num[1]));
            getchar();
            getchar();
        }
    }
    fclose(stdin);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值