【剑指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 == '\0')
	{
		IsValid = false;
		return 0;
	}


	//后面的输入假设合法,则转化为整数
	long num = 0;	//转化为整数后的结果
	//这样能够使相似234asd的输入也判定为合法输入,得到的结果为234
	while(*str != '\0')
	{
		//输入不在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\n",result); else printf("My God\n"); } 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 == '\0')
//	{
//		IsValid = false;
//		return 0;
//	}

	//假设第一个非负号位输入的不是0-9的数字,为非法输入
	if(*str<'0' || *str>'9')
	{
		IsValid = false;
		return 0;
	}

	//后面的输入假设合法。则转化为整数
	long num = 0;	//转化为整数后的结果
	//这样能够使相似234asd的输入也判定为合法输入,得到的结果为234
	while(*str != '\0' && *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\n",result);
		else
			printf("My God\n");
	}
	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')    //'\0'与'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\n", res);
        else if(state==1)
            printf("My God\n");
    }
 
    return 0;
}
/**************************************************************
    Problem: 1508
    User: muddytu
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:912 kb
****************************************************************/
    无力吐槽了。稀里糊涂的搞了整整一个晚上。居然是这种结果。我还是认为第一次的代码是最正确的,不应该将相似123abc这种输入纳入合法的输入范围中。







本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5165180.html,如需转载请自行联系原作者
相关文章
|
5天前
|
存储 人工智能 安全
AI 越智能,数据越危险?
阿里云提供AI全栈安全能力,为客户构建全链路数据保护体系,让企业敢用、能用、放心用
|
8天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
7天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
448 93
|
1天前
|
开发者
「玩透ESA」ESA启用和加速-ER在加速场景中的应用
本文介绍三种配置方法:通过“A鉴权”模板创建函数并设置触发器路由;在ESA上配置回源302跟随;以及自定义响应头。每步均配有详细截图指引,帮助开发者快速完成相关功能设置,提升服务安全性与灵活性。
286 2
|
7天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
406 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
7天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
311 158