科学计数法(PAT)
1.题目描述:
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[±][1-9]"."[0-9]+E[±][0-9]+,即数字的整数部分只有1位,小数部分至少有1位,该数字及其指数部分的正负号即使对正数也必定明确给出。
现以科学计数法的格式给出实数A,请编写程序按普通数字表示法输出A,并保证所有有效位都被保留。
2.输入描述:
每个输入包含1个测试用例,即一个以科学计数法表示的实数A。该数字的存储长度不超过9999字节,且其指数的绝对值不超过9999。
3.输出描述:
对每个测试用例,在一行中按普通数字表示法输出A,并保证所有有效位都被保留,包括末尾的0。
4.输入例子:
+1.23400E-03
5.输出例子:
0.00123400
6.解题思路:
本来打算用字符串输入,用double类型的变量进行计算以普通数字输出,但最后发现关于double类型的变量无法动态控制输出小数点后的位数以及多余零的个数,同时double的范围也不够支撑大数据的输出,所以只能想到通过字符串输出来解题。
1. 创建两个足够的大的数组,一个str[N]用于输入科学计数法的格式,另一个com[N]用于输出转换后的普通数字表示;
2. 首先我们要把输入的科学计数法中字母E之前的字符依次赋值给com[N],对于正数我们要去掉字符’+’,对于负数则将E之前都赋值给com[N];
3. 然后判断str[N]中字母E后面的字符时正号’+‘还是负号’-’,在此间记录str[N]的长度和字母E后[+ -]字符的位置,通过计算其长度来获取10的E次方E的数值;
4. 最后对E的正负号分别判断,如果是正号’+’,则通过移动数组中小数点位置和添加数据0操作来进行转换,如果是负号’-’,则可通过整体向后移动,在小数点后添加数据0元素来进行操作。
7.源代码:
#include<stdio.h>
#include<math.h>
#define N 10000
int main()
{
int i,j,k,n=0;
double m=0,E=0;
char c,str[N]="\0",com[N]="\0";//步骤1
scanf("%s",str);
for(i=0;str[i]!='\0';i++)//步骤2
{
if(str[i]=='E')
{
j=i+1;
break;
}
else
if(str[0]=='+'&&str[i+1]!='E')
com[i]=str[i+1];
else
if(str[0]=='-'&&str[i]!='E')
com[i]=str[i];
}
while(str[i]!='\0')//步骤3
{
i++;
}
for(k=i-1;k>j;k--)//步骤3
E+=(str[k]-48)*(pow(10,n++));
m=E;
if(str[j]=='+')//步骤4
{
for(k=1;k<m+2;k++)
if(com[k]=='.'&&com[k+1]!='\0'&&E!=0)
{
c=com[k];
com[k]=com[k+1];
com[k+1]=c;
E--;
}
else
if(com[k]=='.'&&com[k+1]=='\0'&&E!=0)
{
com[k]='0';
E--;
}
else
if(com[k]=='\0'&&E!=0)
{
com[k]='0';
E--;
}
}
else
if(str[j]=='-'&&E!=0)
{
for(k=0;k<3;k++)
if(com[k]=='.')
{
c=com[k-1];
com[k-1]=com[k];
com[k]=c;
break;
}
for(k=j-1;com[k]!='.';k--)
com[k]=com[k-1];
com[k]='0';
E--;
while(E!=0)
{
for(k=j;com[k-1]!='.';k--)
com[k]=com[k-1];
com[k]='0';
j++;
E--;
}
}
printf("%s",com);
return 0;
}