题目:
科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [±][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
思路:
刚开始的思路是将输入的科学记数法的底数和指数提取到两个新的字符串中,再用转换为数字进行pow运算再输出,但是数字太大了可能没法正确输出。而这道题的本意也是按照科学记数法和普通数字的转换规则,将科学记数法的字符串处理输出,所以得根据指数的大小,对底数字符串进行输出和补0。
代码:
#include <iostream>
#include <cmath>
using namespace std;
int main(){
string input;
string base;
int exp;
cin >> input;
base = input.substr(1, input.find("E")-1);//获取底数
exp = stoi(input.substr(input.find("E")+1, input.length()-input.find("E")-1));//获取指数,指数指定了底数如何偏移,偏移几位
if(input[0] == '-')
cout << input[0];
if(exp > 0){//指数大于0,要向后偏移,并根据指数在后面补0
cout << base[0];//输出小数点前的数字
int i, cnt;//cnt记录已经输出了小数点后几位
for(i = 2, cnt = 0; i < base.length() && cnt < exp; ++i, ++cnt){
cout << base[i];
}
if(i == base.length()){//如果i已经达到底数的长度,说明底数部分已经输出完了,要根据底数在后面补0
//外面定义了全局i,内部最好不要重新定义同名i
for(int k = 0; k < exp-cnt; ++k){
cout << 0;
}
}
else{
cout << ".";//如果指数过小,该数字仍是一个小数,且小数点偏移到当前位置,在此位置输出小数点并且输出后续底数
for(int k = i; k < base.length(); ++k){
cout << base[k];
}
}
}
else{//指数小于0,则需要向前偏移小数点,在前面补0
cout << 0 << ".";
for(int i = 0; i < abs(exp)-1; ++i){//在底数前面补0
cout << 0;
}
for(int i = 0; i < base.length(); ++i){
if(base[i] != '.')
cout << base[i];//输出后续底数
}
}
return 0;
}
学到和回忆了:
-
C++字符串函数
查找字符串中子字符串的位置:s.find(s1)//查找s中第一次出现s1的位置,并返回(包括0)
截取指定位置开始指定数量的字符串:s.substr(pos, n) //截取s中从pos开始(包括0)的n个字符的子串,并返回