PAT Basic Level 1024 科学计数法 解题思路及AC代码 v0.93

1. 题目简述及在线测试位置

1.1 输入是科学计数法格式 ,输出是普通数字表示法格式,要求所有有效位都被保留,包括末尾的0
1.2 在线测试位置:PAT 1024 科学计数法

2. 基本思路

2.1 科学计数法就是将一个数表示成 a与10的n次幂相乘的形式。比如 +1.23400E-03,就是 +1.23400 与 10的-3次方 相乘,E表示10的次方
2.2 通过字符串存储输入的数字,然后以 E 为分隔点,将字符串分割为两部分 E前的字符 1.23400、E后的字符 -03 (对于 首位符号位 不存储,判定后直接打印输出)
2.3 E后的字符用于计算10的次方数

for (int k = afterCount - 1; k >0; k--) // +1.23400E-03 , 将E后 不包含符号的字符(符号位是k=0) 转换为数字,这个数字就是10的次方数
	{
		Base += (After[k] - '0') * Scale; //若Base=3,代表有3个0
		Scale *= 10;
	}

2.4 E前的字符按格式打印输出,本题的难点是 什么时候打印小数点。这里分两个情况:E后的符号为负 -,表示10的负x次方 ; 符号为正,表示10的正x次方。符号为负-时,打印 E前的字符 前,先输出0和小数点:有几次方,就输出几个0,小数点处于第一个0的后面

if (After[0] == '-')   //+1.23400E-03  处理E后为-的情况
	{
		cout << "0"; Base--;
		cout << ".";
		while (Base != 0)
		{
			cout << "0";
			Base--;
		}
		for (j=0; j < beforeCount; j++)
			if (Before[j] != '.')
				cout << Before[j];
		
	}

2.5 符号为正+时,先打印 E前的字符对于小数点之后的数字,边打印、边统计消耗的次方数(即:小数点的移动位置)。这里可以设定一个循环,直到E前的字符打印完再退出,同时判定 次方数的消耗情况。当此循环退出时,可能有三个情况:情况一,循环正常退出,10的次方数中的次方数没打印完,需要补0,此时不用打印小数点 ; 情况二, 循环异常退出(因为10的次方数消耗完了),此时打印小数点 及 其余未打印的字符;情况三,次方数和Before数组都打印完了,此时不需要动作

else if (After[0] == '+') //-1.2E+10 处理E后为+的情况
	{
		cout<<Before[0]; 
		//Before[1]是小数点,先跳过,后面视情况决定什么时候打印
		j=2;
		while (j<beforeCount)  //E前的字符打印完再退出
		{
			cout << Before[j++]; 
			Base--;//对于小数点之后的数字,边打印、边统计小数点的移动位置
			if (Base == 0) 
				break;
		}

		if (Base > 0) //10的次方数中的次方数没打印完
		{
			while (Base != 0)
			{
				cout << "0";
				Base--;
			}
		}
		else if (Base == 0 && j<beforeCount) //次方数打印完了,但是Before数组没打印完,需要加小数点 . 
		{
			cout << ".";
			while (j < beforeCount)
				cout << Before[j++];
		}
		//else  //次方数和Before数组都打印完了

3. 完整AC代码

#include <iostream>
using namespace std;

#define MAX 10000

int main()
{
	string number; // number  +1.23400E-03
	int i=0; //跟踪number数组的位置

	char Before[MAX]; //数组Before用于存储E之前的字符(不包含最前的数值符号)
	char After[MAX]; //数组After用于存储E之后的字符(不包含E)
	int beforeCount = 0,afterCount=0; //Before After数组的计数器
	int j = 0;//跟踪Before After数组的位置

	int Base=0,Scale=1; //10的次方数, 计量单位

	cin >> number;

	if (number[i++] == '-') //打印首位符号位
		cout << "-";

	for (; number[i] != 'E'; i++)//  数组Before用于存储E之前的字符(不包含最前的数值符号)
		Before[beforeCount++]=number[i];
	i++; //跳过字符E
	for (; i < number.length(); i++) //数组After用于存储E之后的字符(不包含E)
		After[afterCount++]=number[i];


	for (int k = afterCount - 1; k >0; k--) // +1.23400E-03 , 将E后 不包含符号的字符 转换为数字
	{
		Base += (After[k] - '0') * Scale; 
		Scale *= 10;
	}

	if (After[0] == '-')   //+1.23400E-03  处理E后为-的情况
	{
		cout << "0"; Base--;
		cout << ".";
		while (Base != 0)
		{
			cout << "0";
			Base--;
		}
		for (; j < beforeCount; j++) //j初始值为0
			if (Before[j] != '.')
				cout << Before[j];
		
	}
	else if (After[0] == '+') //-1.2E+10 处理E后为+的情况
	{
		cout << Before[0]; 
		//Before[1]是小数点,先跳过,后面视情况决定什么时候打印
		j = 2;
		while (j < beforeCount)  //E前的字符打印完再退出
		{
			cout << Before[j++];
			Base--;//对于小数点之后的数字,边打印、边统计小数点的移动位置
			if (Base == 0) //次方数打印完就退出
				break;
		}

		if (Base > 0) //10的次方数中的次方数没打印完
		{
			while (Base != 0)
			{
				cout << "0";
				Base--;
			}
		}
		else if (Base == 0 && j < beforeCount) //次方数打印完了,但是Before数组没打印完,需要加小数点 . 
		{
			cout << ".";
			while (j < beforeCount)
			{
				cout << Before[j++];
			}

		}
		//else  //次方数和Before数组都打印完了	
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值