1024. 科学计数法 (20)

原题: https://www.patest.cn/contests/pat-b-practise/1024

实现思路: 按照前后符号不同可以分4种情况, 分别如下

  1. input: +1.23400E-03 output: 0.00123400
  2. input: -1.2E-10 output: -0.00000000012 (一共10个0)
  3. input: -1.2E+10 output: -12000000000 (一共9个0)
  4. input: +1.23400E+03 output: 1234.00

首先, 经过我的测试, 明确一点, 并不存在E-0, E+0这种情况.
正如我下面的代码定义的变量一样, 通过循环我们需要拿出: 中间字符串, 第1, 第2个符号,
最后的整数.
事实上具体到代码实现, 我们只需要按照第2个符号的不同, 分2种情况即可.
首先是第2个符号是负号, 也就是E-X, 这种形式, 结果肯定是形如0.00123400这种形式,
可以看到, 唯一需要确定就是中间有多少个0的问题, 通过分析可知, 中间需要end-1个0,
也就是E后面数的绝对值-1
第2种情况是后面的符号是正号的情况, 这种情况稍微有点复杂, 需要分成小数点在中间和
小数点在末尾(也就是无小数点)两种情况. 小数点在末尾我们可以通过2次循环, 第1次把我们
提取出来的中间字符串放进结果数组, 第2次把0添加到小数点之前. 小数点在中间的情况只需
遍历我们提取出来的字符串, 在适当的位置插入小数点即可.

完整C语言实现:

#include <stdio.h>

int main () {
    char input[10010];  // 输入字符串
    char one;           // 第1个符号
    char mid[10000];    // 中间数字字符串, 不包括小数点
    int mlen = 0;       // 中间字符串的长度
    char two;           // 第2个符号
    int end = 0;        // 最后的整数
    char res[20000];    // 保存最终结果
    int rlen;           // 结果数组的长度
    int pos;            // 小数点的位置
    char *ptr;
    int i;
    int temp;

    scanf("%s", input);
    one = input[0];
    ptr = input + 1;
    // 把mid[], mlen拿到
    while (1) {
        if (*ptr == '.') {
            ptr++;
            continue;
        }
        mid[mlen] = *ptr;
        mlen++;
        ptr++;
        if (*ptr == 'E') {
            two = *(ptr + 1);
            ptr += 2; // 这时候指向第2符号后面的第1个数字
            break;
        }
    }
    // 把end拿到
    while (*ptr != '\0') {
        end = end * 10 + (*ptr - '0');
        ptr++;
    }

    // 现在搞res结果数组, 一共分2种情况
    if (two == '-') {
        res[0] = one;
        res[1] = '0';
        res[2] = '.';
        rlen = 3;
        // 在[3, end-1]的地方放出'0'
        for (i=1; i<=end-1; i++) {
            res[rlen] = '0';
            rlen++;
        }
        for (i=0; i<mlen; i++) {
            res[rlen] = mid[i];
            rlen++;
        }
    }
    if (two == '+') {
        res[0] = one;
        rlen = 1;
        pos = end + 2; // 小数点的位置
        if (pos >= mlen + 1) {
        // 小数点在末尾
            for (i=0; i<mlen; i++) {
                res[rlen] = mid[i];
                rlen++;
            }
            temp = rlen;
            for (i=temp; i<pos; i++) {
                res[rlen] = '0';
                rlen++;
            }
        } else {
        // 小数点在中间
            for (i=0; i<mlen; i++) {
                res[rlen] = mid[i];
                rlen++;
                if (rlen == pos) {
                    res[rlen] = '.';
                    rlen++;
                }
            }
        }
    }

    // 打印
    for (i=0; i<rlen; i++) {
        // 正号不打印
        if (res[i] == '+') {
            continue;
        }
        printf("%c", res[i]);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凯尔kyle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值