PTA---6-1 atof函数的实现 (10分)

本题要求实现一个函数,将一组数字型字符串,转换成double型的浮点数。

函数接口定义:

函数接口如下:
double myatof(char s[]);

其中s[ ]是输入的数字型字符串,函数返回一个double类型的浮点数。

裁判测试程序样例:

主函数中通过键盘输入一组字符串,调用myatof函数进行转换并打印输出 。
#include "stdio.h"
#define N 20
double myatof(char s[]);

int main()
{
	double num;
	char s[N];
	while(1)
	{
		scanf("%s",s);
		if (s[0]=='q') break;
		num=myatof(s);			
		printf("%f\n",num);

	}
	return 0;	  
}

/* 请在这里填写答案 */

 

输入样例:

输入多个数字型的字符串,每个字符串之间换行符隔开。字符串可能包括空格符、正负符号、小数点以及其它非数字字符。 对输入的字符串进行转换时,首先跳过行首的空格字符,直到遇上数字、小数点或正负符号才开始做转换,而再遇到其它非数字字符时或字符串结束时才结束转换,并将结果返回。 当输入字符'q'时,程序结束。 例如:

6.348
-2.98
.525
q

输出样例:

double型浮点数,显示小数点后六位。 当为正数时,浮点数第一位不显示'+'。 当为负数时,浮点数第一位显示'-'. 如:

6.348000
-2.980000
0.525000

 

 

我的完全错误但结果相同的代码:

double myatof(char s[])
{
	int i,j=1,flag_dot=-1;
	int start=0,end=-5;
	char *a = s;
	double result,item=0;
	for(i=0;a[i]!='\0';i++)     //去除空格
	{
		if(a[i]!=' '&&flag_dot==0)
		{
			start = i;
			flag_dot = 1;
		}
		if(!(a[i]>='0'&&a[i]<='9' || a[i]=='.' || a[i] == '-'))
		{
			end = i-1;
			break;
		}
	}
	if(end==-5)                //记录尾端
	{
		end = i-1;
	}
	
	
	flag_dot = -1;
	a = a+start;
	end -= start;
	
	if(a[0]=='.')       //开始列出 小数, 负数,整数的情况
	{
		for(i=1;i<=end;i++)
		{
			item = item*10+(a[i]-48);
			j *= 10;
		}
		result = item/j;
		return result;
	}
	else if(a[0]>='0'&&a[0]<='9')
	{
		for(i=0;i<=end;i++)
		{
			if(a[i]=='.')
			{
				flag_dot = i;
				break;
			}
		}
		if(flag_dot==-1)
		{
			for(i=0;i<=end;i++)
			{
				item = item*10+(a[i]-48);
			}
			result = item;
			return result;
		}
		else
		{
			for(i=0;i<=end;i++)
			{
				if(a[i]!='.')
					item = item*10+(a[i]-48);
			}
			for(i=flag_dot+1;i<=end;i++)
			{
				j*=10;
			}
			result = item/j;
			return result;
		}
	}
	
	else if(a[0]=='+'||a[0]=='-')
	{
		for(i=1;i<=end;i++)
		{
			if(a[i]=='.')
			{
				flag_dot = i;
				break;
			}
		}
		if(flag_dot==-1)
		{
			for(i=1;i<=end;i++)
			{
				item = item*10+(a[i]-48);
			}
			if(a[0]=='-')
				result = -item;
			else
				result = item;
			return result;
		}
		else
		{
			for(i=1;i<=end;i++)
			{
				if(a[i]!='.')
					item = item*10+(a[i]-48);
			}
			for(i=flag_dot+1;i<=end;i++)
			{
				j*=10;
			}
			result = item/j;
			if(a[0]=='-')
				result = -result;
			return result;
		}
	}
	
}
 

 

参考了同学后自己写的代码:

double myatof(char *str)
{
    char *ch = str;
    int flag=1,i;
    int point=0;
    int pow=1;
    double sum = 0;
    while(!(*ch>='0'&&*ch<='9'||*ch=='+'||*ch=='-'||*ch=='.')&&*ch!='\0')
    	ch++;
    if(*ch=='\0') return 0;	
    
    if(*ch == '-')      //判断负号
        {
        	flag = -1;
            ch++;
        }
    if(*ch == '+')
        { 
            ch++;
		}
    
    while(*ch>='0'&&*ch<='9')  
        {
            sum=sum*10+(*ch-'0');
            ch++;
        }
    
    if(*ch=='.')
    {
    	ch++;
    	while(*ch>='0'&&*ch<='9')
    	{
    		sum=sum*10+(*ch-'0');
    		ch++;
    		pow*=10;
		}
	}
	
    if(sum==0)
    	return 0;
    return flag*sum/pow;
}

 

 

总结:为什么我最开始写的那么繁琐?

区别就在于,我以为必须分情况写,以去除空格后的开头字符是什么来划分。是'+'  '-' ,还是数字 ,还是 '.'  。

而其中涉及一些近似的操作,我是采用的复制+微调。可实际上,在上述代码中,仅仅用了两个标志变量,就解决了问题。

最关键的是,后来的这个代码可读性就很好,把每一步都分开了,一旦有问题也很容易修改。

在最初代码提交时,一直答案错误。是,一旦将代码复杂化,就容易产生各种各样的隐形错误。而很多时候,我们自己是难以看出来的。

那么这也就给了我一些启发,一旦遇到那些感觉过程贼复杂,代码贼繁琐的。不要长时间死扣,不停的补充各种额外情况。不如先想想,有没有什么地方可以优化,比如没必要读完在处理,而是边读边处理等等。看似复杂的问题,往往都有一些经过思考可以发现的简单解法。

 

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值