【全网最细PAT题解】【PAT乙】1024 科学计数法

该文介绍了一种编程问题,涉及将科学计数法表示的数字转换成常规形式,需保留所有有效位,包括末尾的0。解题策略包括定位E字符,分割数字和指数部分,然后根据指数正负处理小数点移动,确保有效位的保留。难点在于处理小数点移动后的零填充和字符串操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

1024 科学计数法

题目描述

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。

现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。

输入格式:
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。

输出格式:
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。

输入样例 1:
+1.23400E-03
输出样例 1:
0.00123400
输入样例 2:
-1.2E+10
输出样例 2:
-12000000000

题目大意

给你一个科学计数法形式的数字,转化为正常形式

解题思路

个人感觉非常恶心的一个题,当时也是放了好久才做,属于那种看到题目就不想做的那种

  • 遇到的第一个问题是判断这个数字是否大于零,这个比较简单,只需要看最一开始的符号是正是负就可以了
  • 然后遇到的问题就是分别求出小数部分和阶数,因为有E这个字符的存在,所以我们可以先找到E,然后1i-1就是小数部分,i+1最后是阶数部分,用substr进行截断,拿题中所给的例子举例
    在这里插入图片描述
  • 还有个问题就是并保证所有有效位都被保留,包括末尾的 0且其指数的绝对值不超过 9999因为有这两条的出现,就导致想改成double类型直接进行运算是行不通的,必须用字符串来模拟小数点的移动,这里就回出现两个问题
    • 小数点左移时,一定会出现0.开头的情况
    • 小数点右移时,会出现两种情况
      • 小数点右移后还存在,这时候末尾的零还需要保留(1.23400123.400
      • 小数点右移后需要补零(1.234001234000)

总之需要满分此题还是有一定难度的,每一步在题解中都有比较详细的注释

题解

#include<bits/stdc++.h>
using namespace std;
int main(){
    string a;
    cin>>a;
    if(a[0]=='-') {
        cout << "-";
    }
    int i=0;
    while(a[i]!='E')	i++;
    string s=a.substr(1,i-1);       //相当于该数字
    string t=a.substr(i+1);             //相当于指数部分
    //substr的用法为
    //string类型变量.substr(开始截断的位置,结束截断的位置)
    //上面两行是从起始位置1(包括1)到位置i-1(包括i-1)
    //和起始位置i+1(包括i+1)到不填(默认最后位置)
    int y=stoi(t);
    if(y<0){
        //y小于零相当于小数点相左移,因为给定的整数部分只有一位,所以一定是0.开头
        cout<<"0.";
        for(int j=0;j<abs(y)-1;j++)	cout<<"0";
        //这里因为已经提前输出了一个0.了所以只需要输出y的绝对值(因为y小于0时才进入这个循环)减1个0,abs是绝对值的意思
        for(int j=0;j<s.length();j++){
            if(s[j]!='.')	cout<<s[j];
//            输出该数字除了小数点以外的所有位数
        }
    }
    else{
        //y大于零相当于小数点右移
        cout<<s[0];
        //因为第一位一定是非零的数字在小数点前,所以先输出第一位
        int cnt,j;
        for(j=2,cnt=0;j<s.length()&&cnt<y;j++,cnt++)	cout<<s[j];
        //这里有两种情况,所以在for循环中需要有两个判断条件
            //1.在小数点右移后,小数点还存在(比如1.234到123.4)
            //2.在小数点右移后,小数点不存在了(1.234到123400)
        if(j==s.length()){
            //这里代表小数点不存在了还要但是还要右移,这时候需要补零
            for(int k=0;k<y-cnt;k++)	cout<<"0";
        }
        else{
            //这里代表右移已经结束了,但是小数点还存在
            cout<<".";
            for(int k=j;k<s.length();k++)	cout<<s[k];
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值