题目链接:
https://pintia.cn/problem-sets/994805260223102976/problems/994805297229447168
思路:首先把情况分为两大类:
1.指数小于0:例:-1.23E-3,转为普通数字:-0.00123,指数为3,则小数点后带2个0,规律如下:设指数为e,小数点后就有e-1个0。
2.指数大于等于0:这个又可以分成两个情况:
- 指数长度小于小数:例:+ 1.2345000E + 3,转为普通数字:1234.5000
- 指数长度大于小数:例:+ 1.23E + 3,转为普通数字:1230
这个在一个循环内就能解决:小数点后移e位,e位前如果没有数值就补0,e位后如果没有数值了就不加小数点了
提升自我:这个 scanf("%c%c.%[0-9]E%d",&h,&a[0],a+1,&e);是在百度上学会的,有关%[]的输入真的很牛。
输入是对其进行拆分,百度出来的极其巧妙的做法:
%[] 的意思是:读入此集合所限定的那些字符。例如 %[A-Z] 是指接受大写字母,一旦遇到非大写字母便停止接受,而 %[^] 是指不要读入此集合所限定的那些字符。例如 % [^A-Z] 是指不接受大写字母,一旦遇到大写字母便停止接受。
填坑日记:数组一定要设置大一点,我原先容量为10000,测试点5老是通不过,看了好几遍代码我觉得还是没啥问题,然后把数组改大一点,就对了。
代码:
#include<iostream>
#include<string>
using namespace std;
int main()
{
char h,a[10001]={0};
int i,e;
scanf("%c%c.%[0-9]E%d",&h,&a[0],a+1,&e);
if(h=='-')
printf("-");
if(e<0) //指数小于0的情况
{
printf("0.");
e=-e-1;
while(e)
{
printf("0");
e--;
}
printf("%s",a);
}
else //指数不小于0的情况
{
for(i=0;i<=e||a[i]!=0;i++)
{
if(i==e+1)
printf(".");
printf("%c",a[i]==0?'0':a[i]);
}
}
return 0;
}
下面又到我们膜拜大佬的时候了:
链接:https://www.liuchuo.net/archives/551
代码:
#include <iostream>
using namespace std;
int main() {
string s;
cin >> s;
int i = 0;
while (s[i] != 'E') i++;
string t = s.substr(1, i-1);
int n = stoi(s.substr(i+1));
if (s[0] == '-') cout << "-";
if (n < 0) {
cout << "0.";
for (int j = 0; j < abs(n) - 1; j++) cout << '0';
for (int j = 0; j < t.length(); j++)
if (t[j] != '.') cout << t[j];
} else {
cout << t[0];
int cnt, j;
for (j = 2, cnt = 0; j < t.length() && cnt < n; j++, cnt++) cout << t[j];
if (j == t.length()) {
for (int k = 0; k < n - cnt; k++) cout << '0';
} else {
cout << '.';
for (int k = j; k < t.length(); k++) cout << t[k];
}
}
return 0;
}
分析:n保存E后面的字符串所对应的数字,t保存E前面的字符串,不包括符号位。当n<0时表示向前移动,那么先输出0. 然后输出abs(n)-1个0,然后继续输出t中的所有数字;当n>0时候表示向后移动,那么先输出第一个字符,然后将t中尽可能输出n个字符,如果t已经输出到最后一个字符(j == t.length())那么就在后面补n-cnt个0,否则就补充一个小数点. 然后继续输出t剩余的没有输出的字符~