自己动手丰衣足食
描述
经历过和S星人的交流之后,他已经对任何交流上的差异都不感到奇怪了。然而这一次,他在和一个A国同学合作时又出现了让他大跌眼镜的事情。那个同学给他的实验数据是用科学计数法表示的,而他需要正常的保留小数点后6位的双精度浮点数。可是不同于我们用2e5来表示200000,他们会使用任何一个字母或者数字中不会出现的字符来表示乘方。这下可麻烦了,本来好好的用atof()函数就解决了,现在这个写好的函数就没法用,只好自己写一个了。阿福为了这份数据已经熬了好几个通宵了,想让你趁他睡觉把这个问题处理一下,你一定可以做到的!
输入
输入多个数字型的字符串,每个字符串之间换行符隔开。字符串可能包括正负符号、小数点以及代表乘方的字符(不是数字,正负号,小数点)。
对输入的字符串进行转换时,遇见数字、小数点或正负符号就开始做转换,字符串结束时才结束转换,并将结果返回。
当输入字符’q’时,程序结束。
输出
double型浮点数,显示小数点后六位。
当为正数时,浮点数第一位不显示’+’。
当为负数时,浮点数第一位显示’-’。
样例输入
+2343.12
-2.36542
-5.21
6.348
+0.564f5
+0.456
-25.1f-5
q
样例输出
2343.120000
-2.365420
-5.210000
6.348000
56400.000000
0.456000
-0.000251
提示
注意:本题严禁使用stdlib.h中的atof()函数,否则不得分。
#include <stdio.h>
#include <string.h>
#include <math.h>
int main()
{
char s[10000];
while (scanf("%s", s))
{
if (s[0] == 'q')return 0;
int n = strlen(s),f=0,z=0,x=0,m=0;
int fuhao[3] = {0,1,1}, xiaoshudian = 0, mici = 0;//指有没有出现过小数点、代表乘方的字符,同时,需要记录整个数的符号和幂次的符号
int zhengshu[10000] = {}, xiaoshu[10000] = {}, mi[10000] = {};
for (int i = 0; i < n; i++)
{
if (mici == 0 && s[i] == '-')fuhao[1] = 0;
else if (mici == 0 && s[i] == '+')fuhao[1] = 1;//正号和没有符号是相同的
else if (mici == 1 && s[i] == '-')fuhao[2] = 0;
else if (mici == 1 && s[i] == '+')fuhao[2] = 1;//正号和没有符号是相同的
else if (s[i] == '.')xiaoshudian = 1;
else if (xiaoshudian == 0 && mici == 0 && s[i] >= '0' && s[i] <= '9')
zhengshu[++z] = s[i]-'0';//总共会有z位小数点之前的数
else if (xiaoshudian == 1 && mici == 0 && s[i] >= '0' && s[i] <= '9')
xiaoshu[++x] = s[i]-'0';
else if (mici == 1 && s[i] >= '0' && s[i] <= '9')
mi[++m] = s[i]-'0';
else mici = 1;
}
double zheng=0.0, xiao=0.0, micishu=0.0;//micishu是e后面的数字
for (int j = z; j >= 1; j--)
{
zheng += (double)zhengshu[j] * pow(10, (double)z - j);//转换的时候最后一位是个位,往前面走乘10
}
for (int j = 1; j <= x; j++)
{
xiao += (double)xiaoshu[j] * pow(0.1, (double)j);
}
for (int j = m; j >= 1; j--)
{
micishu += (double)mi[j] * pow(10, (double)m - j);
if (fuhao[2] == 0)micishu = 0 - micishu;
}
double y = (zheng + xiao) * pow(10, micishu);
if (fuhao[1] == 0)printf("-");
printf("%.6lf\n", y);
}
return 0;
}
其实那个把数组转换为一个数的循环也可以这么写
感觉更稳健一点
double zheng=0.0, xiao=0.0, micishu=0.0;//micishu是e后面的数字
double c1=1.0, c2=0.1, c3=1.0;
for (int j = z; j >= 1; j--)
{
zheng += zhengshu[j] * c1;
c1 *= 10;
}
for (int j = 1; j <= x; j++)
{
xiao += xiaoshu[j] * c2;
c2 *= 0.1;
}
for (int j = m; j >= 1; j--)
{
micishu += mi[j] * c3;
c3 *= 10;
if (fuhao[2] == 0)micishu = 0 - micishu;
}
感觉这道题并不是难想的,但是就是需要比较清晰的思路,把情况考虑清楚,然后想办法实现。
来源:CSDN
作者:huiduu
链接:https://blog.csdn.net/huiduu/article/details/103841773