1.题目描述
Scientific notation is the way that scientists easily handle very large numbers or very small numbers. The notation matches the regular expression [±][1-9].[0-9]+E[±][0-9]+ which means that the integer portion has exactly one digit, there is at least one digit in the fractional portion, and the number and its exponent’s signs are always provided even when they are positive.
Now given a real number A in scientific notation, you are supposed to print A in the conventional notation while keeping all the significant figures.
Input Specification:
Each input contains one test case. For each case, there is one line containing the real number A in scientific notation. The number is no more than 9999 bytes in length and the exponent’s absolute value is no more than 9999.
Output Specification:
For each test case, print in one line the input number A in the conventional notation, with all the significant figures kept, including trailing zeros.
Sample Input 1:
+1.23400E-03
Sample Output 1:
-1.2E+10
Sample Output 2:
-12000000000
2.解题思路
本题要求将计算机中科学计数法表示的结果还原为常规表示法,读题中输入说明可知,E(代表10)后的次方表示不超过9999,因此若以double类型的结果表示将会溢出,考虑使用字符数组或字符串输出结果。
在对输入的科学计数法表示进行处理时,分两种情况:
(1)若E的后一位为负号,则表示需要在E字符前,首位(正或负字符)后添加E后的指数的绝对值个0,在第一次添加的0后添加小数点’.’;
例如样例1:
E后的指数的绝对值是3,则在对E前的字符串去除小数点并添加0.00
(2)若E的后一位为正号,有两种情况
a.如果E后的整数大于或等于原字符串小数点后至E字符前的字符的位数,则对E前的字符串去掉小数点,并在其后添加E后整数-原字符串小数点后至E字符前的字符的位数个0;
b.如果E后的整数小于原字符串小数点后至E字符前的字符的位数,则小数点相对于原字符串需要移动E后的整数个。
基于以上思路,代码如下。
3.注意点
注意对E字符后指数为正数的分情况处理。

AC代码
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
char str[10010];
scanf("%s",str);//用str存储输入的字符串
char c;//c用来记录E后一位的字符为正还是负
int sum=0;//sum用来存储指数部分
int pre=0;//用来记录E后一位正负号在字符串中的位置
if(str[0]=='-')//如果字符串首位为负号则输出
{
printf("-");
}
//找出c,记录pre
for(int i=1;i<strlen(str);i++)
{
if(str[i]=='-'||str[i]=='+')
{
c=str[i];
pre=i;
}
}
//计算指数部分的绝对值存储到sum中
for(int j=pre+1;j<strlen(str);j++)
{
sum=sum*10+str[j]-'0';
}
//判断指数部分为负还是正
if(c=='-')
{
//输出sum个0,并在首次输出0时添加小数点
for(int i=0;i<sum;i++)
{
printf("0");
if(i==0)
{
printf(".");
}
}
//顺次输出E字符前除小数点的各位(关于正负问题上面以处理过,因此从第一个有数的位置开始)
for(int i=1;i<strlen(str);i++)
{
if(str[i]!='E')
{
if(str[i]!='.')
{
printf("%c",str[i]);
}
}else
{
break;//如果遇到E,则输出结束
}
}
}else
{
int count=pre-4;//由于我定义的pre存储的是指数部分位正还是负的数组下标,因此要计算小数点后到字符'E'前的数有几位,要减去包括小数点在内的前三位以及字符'E'占了一位,所以减4
if(sum<count)//判断指数是否大于小数点后的位数
{
int i;
for(i=1;i<=sum+2;i++)//该循环输出最终结果小数点前的部分,sum表示小数点后移几位,从1遍历str到sum+2要加上首位和小数点这两位进行遍历
{
if(str[i]=='.')
{
continue;//遇到小数点不输出,跳过下述语句
}
printf("%c",str[i]);
}
printf(".");//添加小数点
for(int j=i;j<pre-1;j++)//继续输出道E前
{
printf("%c",str[i]);
}
}else
{
//指数部分大于小数部分,只需去掉小数点并在最后添加指数部分减去小数部分个0就可以了
for(int i=1;i<pre-1;i++)
{
if(str[i]=='.') continue;
printf("%c",str[i]);
}
for(int i=0;i<sum-count;i++)
{
printf("0");
}
}
}
return 0;
}
博客围绕将科学计数法表示的实数转换为常规表示法展开。因E后的次方可能使double类型溢出,考虑用字符数组或字符串输出。处理时,根据E后符号分情况:负号时在首位后添加对应个数0和小数点;正号时再分两种情况处理小数点位置或补0。

被折叠的 条评论
为什么被折叠?



