1024 科学计数法 (20 分)
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [±][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
结尾无空行
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
以科学计数法的格式给出实数 A,
按普通数字表示法输出 A,
并保证所有有效位都被保留。
其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+
*/
/*
包括以下几个部分:
正负号、实数、E、正负号、幂次
根据E后正负号决定小数点向前/后移位
*/
void function(char e[10000])
{
/*先将原数中的底数部分去掉小数点存储起来(+省-存)
其次判断小数点是前移还是后移
前移的话,普通数字开头必是“0.”,然后小数点后添零即可
后移的话,判断底数部分小数尾数和幂次的大小关系,
若尾数长度大于幂次,则小数点按需后移;
若尾数长度小于幂次,则无小数点,并按需在最后添零
*/
//首先记录科学计数中小数点、E所在位置
int xsd,Ewz; //小数点xsd,E Ewz
int len; //科学计数长度
int i;
int ws; //底数中尾数长度
int mc=0; //幂次
len = strlen(e);
for(i=0;i<len;i++)
{
if(e[i]=='.')
xsd = i+1; //下标从0开始
if(e[i]=='E')
Ewz = i+1; //下标从0开始
}
ws = Ewz - xsd - 1;
for(i=Ewz+1;i<len;i++)
{ //E后面还有一个正负号
mc = mc*10 + (e[i]-'0'); //得到幂次
}
// printf("%d,%d,%d,%d\n",xsd,Ewz,ws,mc);
//其次,将原数中的底数部分去掉小数点按正负存储
char c[10000];
int cl=0; //用于记录c长度
if(e[0]=='-')
c[cl++] = e[0];
for(i=1;i<Ewz-1;i++)
{
if(e[i]=='.')
;
else
c[cl++] = e[i];
}
// for(i=0;i<cl;i++)
// printf("%c",c[i]);
// printf("\n");
//开始分类,小数点前移/后移
char zz[10000]; //存储最终普通数字
int zzl=0; //记录zz长度
if(e[Ewz]=='-') //Ewz从1开始,所以不用减零
{//小数点前移,则普通数字开头必是“0.”
zz[zzl++]='0';
zz[zzl++]='.';
for(i=0;i<mc-1;i++) //开头有一位0了,所以i到 mc-1
zz[zzl++]='0';
for(i=0;i<cl;i++)
zz[zzl++]=c[i];
}
else
{//小数点后移,分两种情况
if(ws > mc)
{//第一种是小数位ws大于幂次mc,则结果中仍含有小数点
//小数点向后移mc位,即c[]中数字保留mc+2位(还有正负号和整数位)后加一个小数点
//要注意,c[]中正号是省略的,则只要保留mmc+1位
if(c[0]=='-')
{
for(i=0;i< mc+2;i++)
zz[zzl++]=c[i];
}
else
{
for(i=0;i< mc+1;i++)
zz[zzl++]=c[i];
}
zz[zzl++]='.';
for(;i<cl;i++)
zz[zzl++]=c[i];
}
else
{//第二种情况,小数位ws小于等于幂次mc,则结果中无小数点,甚至需要添零(添幂次-尾数位个0)
for(i=0;i<cl;i++)
zz[zzl++]=c[i];
for(i=0;i<mc-ws;i++)
zz[zzl++]='0';
}
}
for(i=0;i<zzl;i++)
printf("%c",zz[i]);
}
void main()
{
char e[10000];
scanf("%s",&e);
function(e);
}
时隔八个月,我又回来了!
咳,我发现写代码一开始总是逻辑混乱,当发现已经乱成一团毛线球了,解不开了,才会回头去重新分析,这个习惯不好,得改。
另外,这个代码在测试点6有运行时错误,以后再改吧。