PAT 解题报告 1073. Scientific Notation (20)

1073. Scientific Notation 题目描述:

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.

给出一个数值的科学表达式, 要求输出这个值的普通的十进制表达式, 并且保留所有有效位, 比如

+1.23400E-03 则要求输出 0.00123400 // 注意保留有效的零

1073. Scientific Notation 算法分析:

题目本身没有什么算法可言, 但是因为要保留有效位(零什么的), 于是直接转换成数值(利用atoi, atof之类的函数)的途径不可行, 应为转换过了比如上面的1.23400里面的有效零就丢了, 于是还是模拟吧, 科学计数法, 因为题目限定的格式比较固定, 比如正负号一定会给出, E一定会有, 于是就先找到E的位置, 然后得到E后面的幂次的值, 如果是正的, 则原先的小数点往后移动 E 个单位, E 是幂次的绝对值, 如果是负数, 则小数点向左移动 E 位, 也就是模拟科学计数法得到普通的数值的过程, 其中注意原来小数点的位置就可以了(因为给出的格式比较固定, 这个也不难), 下面是可以AC的代码:
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <iostream>

int main() {
	std::string strInput;
	std::getline(std::cin, strInput);

	int iPos = strInput.find('E');

	std::string strSignificant = strInput.substr(0, iPos);
	int iExp = atoi(strInput.substr(iPos + 1).c_str());

	if('-' == strSignificant[0])
		std::cout << '-';
	strSignificant = strSignificant.substr(1);

	if(0 == iExp)
		std::cout << strSignificant;

	if(iExp < 0) {
		std::cout << "0." ;
		int iCount = -iExp - 1;
		while(iCount--)
			std::cout << '0';
		iCount = strSignificant.size() - 1;
		for(int i = 0; i <= iCount; ++i)
			if('.' != strSignificant[i])
				std::cout << strSignificant[i];
	}

	if(iExp > 0) {
		if(iExp >= strSignificant.size() - 2) {
			strSignificant.append(iExp - strSignificant.size() + 2, '0');
			for(int i = 0; i < strSignificant.size(); ++i)
				if('.' != strSignificant[i])
					std::cout << strSignificant[i];
		}
		else {
			std::cout << strSignificant[0] << strSignificant[2];
			int iLen = iExp - 1;
			int idx = 0;
			for(idx = 0; idx < iLen; ++idx)
				std::cout << strSignificant[3 + idx];
			std::cout << '.' << strSignificant.substr(3 + idx);
		}
	}

	std::cout << std::endl;
	return 0;
}
Written on March 6, 2014