题目:
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].
[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。
现以科学计数法的格式给出实数 A,请编写程序按普通数字表示法输出 A,并保证所有有效位都被保留。
输入格式:
每个输入包含 1 个测试用例,即一个以科学计数法表示的实数 A。该数字的存储长度不超过 9999 字节,且其指数的绝对值不超过 9999。
输出格式:
对每个测试用例,在一行中按普通数字表示法输出 A,并保证所有有效位都被保留,包括末尾的 0。
输入样例 1:
+1.23400E-03
输出样例 1:
0.00123400
输入样例 2:
-1.2E+10
输出样例 2:
-12000000000
本人思路:
- 首先判断科学计数法的小数点和E的位置以及E后面的值。
- 判断小数点应该左移还是右移,如果E后面是“-”就是左移,E后面是“+”就是右移。
- 其实完全不需要考虑这个数是正数还是负数,先一并处理到同一个数组中去,输出的时候判断即可。
注意事项:
- 科学计数法就是E前面的数 × 10^(E后面的数),感觉题目给的不是很清楚
- 小数点右移的时候要记得看看右移有没有超过E前面的数,有的话要在末端加0。
- 题目说,整数部分只有 1 位,因此如果小数点左移,就可以直接在输出的数组中加上“0.”,再加上E后面的数-1个0。
- 题目说数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指数部分的正负号即使对正数也必定明确给出。那就是说输入进来的科学计数法的数组第一位必然是正负号,第二位是数字,第三位是小数点,直接拿这数组的三个下标做判断会更快。
代码:
#include <iostream>
#include <vector>
using namespace std;
string sciencenum;
vector<char> rnum;
int e = 0, dit = 2, e_num = 0;
int main(){
cin >> sciencenum;
for(int i = 3; i < sciencenum.size(); i++){ // 找E的位置
if(sciencenum[i] == 'E'){
e = i;
for(int j = e + 2; j < sciencenum.size(); j++){ // 算E后面的数的值
e_num = e_num * 10 + (sciencenum[j] - '0');
}
break;
}
}
if(sciencenum[e + 1] == '-'){ // 小数点左移情况
rnum.push_back(sciencenum[0]); // 输出正负号
rnum.push_back('0');
rnum.push_back('.');
while((e_num - 1)){ // 应该在小数点后面输出几个0
rnum.push_back('0');
e_num --;
}
for(int i = 1; sciencenum[i] != 'E'; i++){ // 剩余数输出
if(sciencenum[i] != '.') rnum.push_back(sciencenum[i]);
}
}
else{ // 小数点右移情况
rnum.push_back(sciencenum[0]);
rnum.push_back(sciencenum[1]);
int i = 3;
if(e_num < e - 3){ // E后面的数 小于 小数点到E的个数,因此需要输出小数点
for(i; i < 3 + e_num; i ++){
rnum.push_back(sciencenum[i]);
}
rnum.push_back('.');
for(i; sciencenum[i] != 'E'; i++) rnum.push_back(sciencenum[i]);
}
else{ // E后面的数 不小于 小数点到E的个数,因此不需要输出小数点
for(i; sciencenum[i] != 'E'; i++) rnum.push_back(sciencenum[i]);
while(e_num - (e - 3)){
rnum.push_back('0');
e_num --;
}
}
}
for(int i = 0; i < rnum.size(); i ++){
if(rnum[i] != '+') cout << rnum[i]; // 去掉最前面的+并输出
}
return 0;
}