博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【剑指offer】字符串转整数
阅读量:5736 次
发布时间:2019-06-18

本文共 4303 字,大约阅读时间需要 14 分钟。

转载请注明出处:

题目描写叙述:

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

输入:

输入可能包括多个測试例子。

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

输出:

相应每一个測试案例,

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

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

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

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

#include
#include
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
#include
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
#include
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,如需转载请自行联系原作者
你可能感兴趣的文章
数据传输流程和socket简单操作
查看>>
利用广播实现ip拨号——示例
查看>>
ProbS CF matlab源代码(二分系统)(原创作品,转载注明出处,谢谢!)
查看>>
OC中KVC的注意点
查看>>
JQ入门(至回调函数)
查看>>
【洛天依】几首歌的翻唱(无伴奏)
查看>>
OpenSSL初瞻及本系列的博文的缘由
查看>>
ISO8583接口的详细资料
查看>>
tmux不自动加载配置文件.tmux.conf
查看>>
经验分享:JavaScript小技巧
查看>>
[MOSEK] Stupid things when using mosek
查看>>
程序实例---栈的顺序实现和链式实现
查看>>
服务的使用
查看>>
Oracle 用户与模式
查看>>
MairDB 初始数据库与表 (二)
查看>>
拥在怀里
查看>>
chm文件打开,有目录无内容
查看>>
whereis、find、which、locate的区别
查看>>
一点不懂到小白的linux系统运维经历分享
查看>>
桌面支持--打不开网页上的pdf附件解决办法(ie-tools-compatibility)
查看>>