科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][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
关于测试点4,主要测试指数小于小数位情况,当时写代码的时候偶然试验发现没写一种情况只有测试点4显示答案错误。后来写完后发现仍然无法通过,于是想取巧,通过用if加一个while永真循环(我的代码中也可以看到,只不过注释掉了),锁定了指数为2,多次使用该方法后,得出测试点4数据
在测试过程中也发现了测试数据的缺失,详见代码注释部分,已经将数据缺失问题反馈给了pta。
另外关于测试点6,主要引起错误原因可能是接收字符串的空间不足,建议扩大存放接收数据的数组大小,第一次我使用10000大小的,测试点6无法通过,但是将数组扩充为10001时候程序通过测试点6.
主要考虑这几种情况:
1.指数小于0:例:-1.23E-3,转为普通数字:-0.00123,指数为3,则小数点后带2个0,规律如下:设指数为e,小数点后就有e-1个0。
2.指数大于等于0:这个又可以分成两个情况
指数长度小于小数:例:+ 1.2345000E + 3,转为普通数字:1234.5000
指数长度大于小数:例:+ 1.23E + 3,转为普通数字:1230
代码如下:
#include<stdio.h>
#include<string.h>
int main(){
char receive[10001];
int exp;
gets(receive);
for(int i=0;i<strlen(receive);i++)
if(receive[i]=='E'){
receive[i]='\0';
break;
}
exp=atoi(&receive[strlen(receive)+1]);
if(receive[0]!='+')
printf("%c",receive[0]);
if(exp<0){
exp*=-1;
printf("0.");
if(receive[1]-'0'){
char t=receive[2];
receive[2]=receive[1];
receive[1]=t;
exp--;
while(exp){
printf("0");
exp--;
}
puts(&receive[2]);
}else{
while(exp){
printf("0");
exp--;
}
puts(&receive[3]);
}
}else{
if(exp>=(strlen(receive)-3)){
exp-=strlen(receive)-3;
int key=1;
while(receive[key]=='0'||key==2)
key++;
for(int i=key;i<strlen(receive);i++)
if(i!=2){
printf("%c",receive[i]);
}
while(exp){
printf("0");
exp--;
}
}else{
int key=1;
while(receive[key]=='0'||key==2)
key++;
if(key>(exp+2)){
printf("0.");
puts(&receive[exp+3]);
}else{//此处为测试点4,用条件符合循环运行超时证明测试点4的exp=2,-9.870
//if(receive[1]-'0')//可以注释掉此行代码,仍会通过,但是如果输入例如-0.870E+2,运行结果为-870.,明显错误
exp++;
for(int i=key;i<strlen(receive);i++){
if(i==2)
continue;
printf("%c",receive[i]);
exp--;
if(!exp)
printf(".");
}
// if(receive[0]=='+')
// while(1)
// printf("hello");
// printf("987.0");
}
}
}
return 0;
}
运行结果