PAT甲级 1073 Scientific Notation (20分)

博客围绕将科学计数法表示的实数转换为常规表示法展开。因E后的次方可能使double类型溢出,考虑用字符数组或字符串输出。处理时,根据E后符号分情况:负号时在首位后添加对应个数0和小数点;正号时再分两种情况处理小数点位置或补0。

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;
	
} 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值