July大神交大读书会子atoi
来源:互联网 发布:北理工 大数据联盟 编辑:程序博客网 时间:2024/05/17 02:53
犹记得July大大在今年交大一次读书会上让大家10min写这个算法,然后讲解这个算法,我是通过百度网盘的视频看的,我10min没写出来,而且还是在输出exception case的几次提示下才AC掉的,而且关于需求分析还差了cplusplus的说明= =
今天写了这个函数,一开始想估计有千万种情况考虑,但是细细一想,其实也是可以枚举出来的,关键就是逻辑要能处理所有的case,
我已开始居然连需求都没弄清楚,他是允许非法字符的,只要前面有一些可以产生数值的,例如-9a.986返回-9,-9.a8a77a 返回-9,这感觉有点奇怪,我觉得出现非 + - . 0-9的就都是非法了,不知道系统设计出于什么目的。
设计逻辑了,前缀我主要分为4种:
1) [+|-] [(0-9)上加号] [非法或.]
2) [(0-9)上加号] [非法或.]
3) [+ | -] .
4) .
主要分为这些,然后先看第一个是否符号位,是的话i++, 然后这时判断i是否越界(每次i++ i--都要判断是否可能越了上下界,有的话就特殊处理,我又一次就这么错了),如果是的话,说明只有符号位,返回非法字符。否则从后面找连续的数字,然后同时loop 要判断是否越界,发现越界可以统一处理~ 然后后面算值,这部分比较简单,我又一次居然直接用ASCII码算= = 然后最后如果负数的话,根据之前的 符号判断,sum-=2*sum, 我出现正负数一起处理都是这样把两者统一成正数处理,这样逻辑比较清晰。
还有最最难想到的就是溢出了,从给的case来看如果上溢返回上届,下溢返回下届,所以需要再加完之后就判断,我之前还在最后判断发现已经没用了,sum已经因为溢出错了= = 然后如果上溢了,就返回上届,因为int是补码范围,负变正后负数最大会多一个,也即-2^31,但是发现这个case可以统一到里面,因为2^31溢出恰好变为-2^31,于是直接返回下届是对的。
我还有一次直接写2^31-1结果就不知道C++认为是什么了= =(后来发现了,是异或操作,2^31得到29然后-1得28,发现2^31=29=31-2,好像还有点规律可以挖掘)我有时候还会犯从数学到代码转换的一个缺口,甚至左右赋值都写错过一次,感觉程序设计和数学思维会有些不同
最后的最后,附上修改几次后的代码:
int myatoi(const char* str){string cppstr=str, intstr;istringstream istr(cppstr);int isnegative=false,i=0;while(istr>>intstr){if(intstr.at(0)=='-'){isnegative=true;i++;}if(intstr.at(0)=='+'){i++;}if(i==intstr.size())//whether only + - return 0;if(intstr.at(i)=='.')return 0;int starti=i;while(i<intstr.size()&&intstr.at(i)<='9'&&intstr.at(i)>='0')i++;int endi=i-1;int sum=0,weighti=0;for(int k=endi;k>=starti;k--,weighti++)sum+=(intstr.at(k)-'0')*pow(10.0, weighti);if(sum<0) //overflow{if(isnegative==false)return pow(2.0,31)-1;elsereturn -pow(2.0,31);}if(isnegative==true)sum-=2*sum;return sum;}if(intstr.size()==0)return 0;}
代码质量太差了,这个是经典面试题,考察程序员的鲁棒性能力。
一下是代码,需要注意
1.正负号
2.上下溢出
3高位到低位逐个移动,计算sum和从低位的区别
4.用isdigit里面是字符,不是数值,例如'0' '9'
5. 判溢出要注意 >214748364 或者= 214748364 && *str>='8' 要这样,之前犯了一次错误
下面的是代码
int atoi(const char* str){bool flag=1;while((*str)==' ') str++;if((*str)=='+') str++,flag=1;else if((*str)=='-') str++,flag=0;int sum=0;while(isdigit(*str)){if(flag){if(sum >214748364 || sum==214748364 && (*str)>='8' ) {return (int)((1<<31)-(unsigned int)1);}}else{if(sum>214748364 || sum==214748364 && (*str)>='9') {return (int)(1<<31);}}sum*=10;sum+=((*str)-'0');str++;}return flag? sum : -sum;}
这个代码应该是比较简洁版的。实现较为方便。
- July大神交大读书会子atoi
- July大神的大数据解决思路
- 【和JULY大神学算法】左旋转字符串
- CSDN大神JULY:程序员如何快速准备面试中的算法
- July大神关于面试中算法学习的总结
- github-july-最长回文子串
- PRML读书会
- 【July第3题】求子数组的最大和
- 关于链表的算法..对于july大神的文章的学习笔记
- 关于堆栈的算法...对于july大神的文章的学习笔记
- 关于数组的算法...对于july大神的文章的学习笔记
- 交大1102
- 交大1093
- atoi
- atoi
- atoi
- atoi()
- atoi
- 编外话4
- 关于list_entry
- Opencv与CUDA
- Ubuntu下安装eclipse
- perl 正则式 关于分组匹配的4个测试
- July大神交大读书会子atoi
- webViewDemo
- 移动互联网应用的十项设计原则和小提示
- Android提高第二篇之SurfaceView的基本使用
- javascript版 2048游戏
- android:inputType常用取值
- 黑马程序员_模拟Spring可配置的AOP框架
- MyEclipse新建Web Project报错
- ps的开发历程及