zoukankan      html  css  js  c++  java
  • 【剑指offer】字符串转整数

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/28015693

    题目描写叙述:

    将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。

    输入:

    输入可能包括多个測试例子。
    对于每一个測试案例,输入为一个合法或者非法的字符串,代表一个整数n(1<= n<=10000000)。

    输出:

    相应每一个測试案例,
    若输入为一个合法的字符串(即代表一个整数)。则输出这个整数。
    若输入为一个非法的字符串,则输出“My God”。

    例子输入:
    5
    -5
    +8
    
    例子输出:
    5
    -5
    8
        关于这道题目。题目本身还是不错的。真正核心的代码也就那么两行,大部分代码基本都在做非法输入的检查。

        近期做这几道题目,对九度后台的測试用例有点无语了,这道题目的測试用例应该有问题。我写的代码自己測试了非常多种不同的非法输入以及合法输入,都没问题,可是在九度OJ上仅仅有第四条測试用例通过,其它四条所有WA,害的我搞了一个晚上,后来下了个别人AC的代码,拿来測试了下。结果各种非法的输入都没处理,非常多非法的输入,得到的都是些五花八门的答案。

        先贴上代码。大家帮我看下有木有没考虑到的地方:

    #include<stdio.h>
    #include<stdbool.h>
    bool IsValid;
    
    long StrToIInt(const char *str)
    {
    	//非法输入
    	if(str == NULL)
    	{
    		IsValid = false;
    		return 0;
    	}
    
    	//是否为负数
    	bool IsMinus = false;
    
    	//跳过前面的空白字符
    	while(*str == ' ')
    		str++;
    
    	//第一个非空白字符为+号
    	if(*str == '+')
    		str++;
    	//第一个非空白字符为-号
    	else if(*str == '-')
    	{
    		str++;
    		IsMinus = true;
    	}
    
    	//假设仅仅输入了空白字符、符号位,或者什么都没输入,也为非法输入
    	if(*str == '')
    	{
    		IsValid = false;
    		return 0;
    	}
    
    
    	//后面的输入假设合法,则转化为整数
    	long num = 0;	//转化为整数后的结果
    	//这样能够使相似234asd的输入也判定为合法输入,得到的结果为234
    	while(*str != '')
    	{
    		//输入不在0-9之间。属于非法输入
    		if(*str<'0' || *str>'9')
    		{
    			IsValid = false;
    			return 0;
    		}
    		//对不包括符号位的合法输入进行转换
    		num = 10*num + (*str - '0');
    		str++;
    	}
    	
    	//依据符号位转换正负
    	num = IsMinus ?

    (-1*num) : num; //推断是否溢出了int的范围 if(num>0X7FFFFFFF || num<(signed int)0X80000000) { IsValid = false; return 0; } //上面没有返回,则说明合法并没有发生溢出 return num; } int main() { static char str[100000000]; while(gets(str) != NULL) { IsValid = true; long result = StrToIInt(str); if(IsValid) printf("%ld ",result); else printf("My God "); } return 0; }

        最后查到有些人讲相似123abc这种输入也作为合法输入。这样得到的结果是123,去掉了后面的非法字符。我就索性又把程序改了下,把这种情况纳入合法输入的范围内。改成例如以下代码:

    #include<stdio.h>
    #include<stdbool.h>
    bool IsValid;
    
    long StrToIInt(const char *str)
    {
    	//非法输入
    	if(str == NULL)
    	{
    		IsValid = false;
    		return 0;
    	}
    
    	//是否为负数
    	bool IsMinus = false;
    
    	//跳过前面的空白字符
    	while(*str == ' ')
    		str++;
    
    	//第一个非空白字符为+号
    	if(*str == '+')
    		str++;
    	//第一个非空白字符为-号
    	else if(*str == '-')
    	{
    		str++;
    		IsMinus = true;
    	}
    
    	//假设仅仅输入了空白字符、符号位,或者什么都没输入。也为非法输入
    //	if(*str == '')
    //	{
    //		IsValid = false;
    //		return 0;
    //	}
    
    	//假设第一个非负号位输入的不是0-9的数字,为非法输入
    	if(*str<'0' || *str>'9')
    	{
    		IsValid = false;
    		return 0;
    	}
    
    	//后面的输入假设合法。则转化为整数
    	long num = 0;	//转化为整数后的结果
    	//这样能够使相似234asd的输入也判定为合法输入,得到的结果为234
    	while(*str != '' && *str>='0' && *str<='9')
    	{
    		//输入不在0-9之间,属于非法输入
    	//	if(*str<'0' || *str>'9')
    	//	{
    	//		IsValid = false;
    	//		return 0;
    	//	}
    		//对不包括符号位的合法输入进行转换
    		num = 10*num + (*str - '0');
    		str++;
    	}
    	
    	//依据符号位转换正负
    	num = IsMinus ? (-1*num) : num;
    	//推断是否溢出了int的范围
    	if(num>0X7FFFFFFF || num<(signed int)0X80000000)
    	{
    		IsValid = false;
    		return 0;
    	}
    
    	//上面没有返回,则说明合法并没有发生溢出
    	return num;
    }
    
    int main()
    {
    	static char str[100000000];
    	while(gets(str) != NULL)
    	{
    		IsValid = true;
    		long result = StrToIInt(str);
    		if(IsValid)
    			printf("%ld
    ",result);
    		else
    			printf("My God
    ");
    	}
    	return 0;
    }
        这次居然前三个測试用例通过了,后面两个WA了,搞得我晕头转向。下载了个别人的AC代码,一眼看过去就感觉非常多非法输入没有考虑到,測试了下,确实非常多非法的输入,得到的结果五花八门。

    贴出来大家瞅瞅。分析下看是不是这道题的后台測试用例有问题。

        别人AC的代码:

    #include<stdio.h>
    #include<stdlib.h>
     
    int state=0;
     
    long StrToInt(const char * str)
    {
        long num;
        num = 0;
     
        if(str!=NULL)
        {
            const char * digit = str;
     
            int minus = 0;                              //推断正负(第一个字符)
     
            if(*digit=='+')
            {
                digit++;
            }
            else if(*digit=='-')
            {
                minus = 1;
                digit++;
            }
     
     
            while(*digit!='')    //''与'0'差别
            {
                if(*digit>='0' && *digit<='9')
                    num = 10*num+(*digit-'0');
                else
                {
                    state=1;
                    num=0;
                    break;
                }                              //输入不合法
                digit++;
                state=0;
            }
     
            if(minus)
            {
                num = 0 - num;
            }
     
        }
     
        return num;
     
    }
     
    int main()
    {
        long res;
        char st[100];
        char *p = st;
         
        while(scanf("%s", p)!=EOF)     
        {
            res = StrToInt(p);
     
            if(state==0)
                printf("%ld
    ", res);
            else if(state==1)
                printf("My God
    ");
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1508
        User: muddytu
        Language: C
        Result: Accepted
        Time:0 ms
        Memory:912 kb
    ****************************************************************/
        无力吐槽了。稀里糊涂的搞了整整一个晚上。居然是这种结果。我还是认为第一次的代码是最正确的,不应该将相似123abc这种输入纳入合法的输入范围中。



  • 相关阅读:
    数论
    平衡树
    矩阵儿快速幂
    分治
    考试
    考试
    匈牙利算法
    SPFA
    倍增
    MySql 技术内幕 (数据库组成和引擎)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5165180.html
Copyright © 2011-2022 走看看