1024 科学计数法 (20 分)

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
#include
#include
/*
以科学计数法的格式给出实数 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
//        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有运行时错误,以后再改吧。	

你可能感兴趣的:(PAT,c语言)