LeetCode 8_String to Integer (atoi)
2015-09-02 19:27
274 查看
这几天时间比较宽松,尽量多整理几道吧,希望每个人的努力都能换来想要的生活。。。
这是leetcode第八题,说实在的,本人感觉是出的不如前面几道,这道题怎么说呢,很平常,但一些特殊情况考虑的很多很杂散,不像是在做算法,倒像是在玩儿“找茬儿”,我着重说点有用的吧,原题如下:
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
题目的要求可以用一句话说明白:把字符串转化为整数。
这个想对于一点儿编程基础的人都不会有什么问题,而题目中的Notes也说了,这个题目主要是考察你对“各种”输入的考虑是否周全。字符串转数字大家时并不是都能转化的,这一点大家都能理解。比如说字符串中有不是数字的字符,再进一步可能会考虑的有负数,再再进一步可能会考虑到转化溢出的情况。个人认为能考虑到这些基本就可以了,不过通过编程发现其实要通过验证还要处理很多“变态输入”。比如,字符串中有空格,这种情况本来就应该是每个情况都有自己处理方式的,但题目中并没有这样的具体要求,通过实验发现题目是要求把前面的空格忽略,然后中间的空格当做一般的非数字字符处理。而对于非数字字符的处理也挺奇怪,遇到非数字字符时转化停止,只算前面的数字就可以了,总之这种情况很多,其实只要要求明确了,这些并不算难,但题目中没有要求,要通过实验得到,好像评判标准也是凑出来的,好了不吐槽了,上代码吧。
(1)“-”和“+”。一般人可能会想到符号而忘了正号,这种“灯下黑”的错误还是要注意一下的。
(2)不是数字的情况。这个大家一定要考虑到,这是转化数字最基本的要求嘛。
(3)溢出判断。这一点要在这里着重说一下,并为上一题(第七题)的错误作出改正。
溢出判断也是数字转化过程中要注意的很重要的一点,严谨的说,每一次算术都有溢出的可能,所以每次运算都应该进行溢出判断。当然实际编程过程中溢出毕竟只是少数情况,所以一般是不需要进行判断的,但这种转化的题目就必须要考虑了,因为这不是一个实际中的有意义的数值,而是通过机械式的转化得到的一种形式或者成为符号。
那该怎么进行溢出判断呢?是在运算前,还是运算后?是利用符号改变还是大小改变?这些情况很多,我们先来看一下溢出的本质:
我们知道(我假设你知道,不知道的话可以查看相关资料)数字在机器中,也可以说在电脑中,是用补码表示的,那数字的补码是怎么表示的呢,又是怎么溢出的呢,我们不去讨论里面的各种原理,只是来看一些实例:假设某种型的存储空间为4为二进制编码,我们知道,它一共可以表示2^4=16种不同的数字,我们就让它来表示-8—7这16个数字。-8—7的原码、反码和补码列于下表:
![](http://img.blog.csdn.net/20150902190644816?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
从这个图中可以看到,-0和+0的原码是不同的,但补码是相同的,所以“多出来“的位置正好给了-8,而没有+8。另外通过补码一列我们可以总结出这样的规律:补码从0000到1111,对应的数字为从0到7然后突变成-8然后到-1。而这里的突变点,就是我们所说的溢出点,也就是说7再加1就溢出了(本来应该是8,变成-8了),而-8再减1也会溢出(本来应该是-9变成7了)。从突变点看貌似可以通过符号的改变判断是否溢出,但仔细思考一下会发现,这只是”小的“溢出,如果7再加16呢?它还是7!所以这种方法是不对的。我们在上一题中提到了用”还原法“,当时并没有出现错误且通过了验证,但通过今天的分析我们知道,其实上次的成功只是侥幸罢了。能还原的并不一定没有溢出,当然不能还原的是一定溢出了,这个例子就不用再举了吧。那么话说回来,我们该怎么判断溢出呢?
通过分析可知,溢出是一个很随意的过程,溢出的结果也是很难捉摸。所以我们应该把溢出扼杀在摇篮里,也就是说要把”溢出后判断“的思维改为”判断要溢出“。说直白点儿,就是在运算前判断是否会溢出,有了这个思路就容易入手了,具体的语句已经写在程序里了。如果你还是会写成if(result*10>INT_MAX),那证明,怎么说呢,你要走的路还很长啊,加油吧。
明天是抗战70周年的纪念日,在此向我们的革命先烈致以敬意,也希望每个人都能珍惜来之不易的和平,珍惜来之不易的幸福生活。
这是leetcode第八题,说实在的,本人感觉是出的不如前面几道,这道题怎么说呢,很平常,但一些特殊情况考虑的很多很杂散,不像是在做算法,倒像是在玩儿“找茬儿”,我着重说点有用的吧,原题如下:
Implement atoi to convert a string to an integer.
Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
题目的要求可以用一句话说明白:把字符串转化为整数。
这个想对于一点儿编程基础的人都不会有什么问题,而题目中的Notes也说了,这个题目主要是考察你对“各种”输入的考虑是否周全。字符串转数字大家时并不是都能转化的,这一点大家都能理解。比如说字符串中有不是数字的字符,再进一步可能会考虑的有负数,再再进一步可能会考虑到转化溢出的情况。个人认为能考虑到这些基本就可以了,不过通过编程发现其实要通过验证还要处理很多“变态输入”。比如,字符串中有空格,这种情况本来就应该是每个情况都有自己处理方式的,但题目中并没有这样的具体要求,通过实验发现题目是要求把前面的空格忽略,然后中间的空格当做一般的非数字字符处理。而对于非数字字符的处理也挺奇怪,遇到非数字字符时转化停止,只算前面的数字就可以了,总之这种情况很多,其实只要要求明确了,这些并不算难,但题目中没有要求,要通过实验得到,好像评判标准也是凑出来的,好了不吐槽了,上代码吧。
class Solution { public: int myAtoi(string str) { //滤除空格 string str1; string::iterator it=str.begin(); for(;*it==' ';++it); for(string::iterator it2=it;it2!=str.end();++it2) { str1.push_back(*it2); } str=str1; //确定是否有正负号 bool neg=false; if(str[0]=='-')//前面有负号 neg=true; bool pos=false; if(str[0]=='+')//前面有正号 pos=true; int len=str.size(); int result=0; for(int i=(neg||pos)?1:0;i<len;++i) { if(str[i]<'0'||str[i]>'9')//不是数字,返回 return neg?(-1*result):result; if(result > INT_MAX/10)return neg?INT_MIN:INT_MAX; result *= 10; if(result > INT_MAX-str[i]+'0')return neg?INT_MIN:INT_MAX; result += str[i]-'0'; } return neg?(-1*result):result; } };里面的各种“补丁”语句大家没必要纠结,大体思路明白就好了,注意并学会这几点就好:
(1)“-”和“+”。一般人可能会想到符号而忘了正号,这种“灯下黑”的错误还是要注意一下的。
(2)不是数字的情况。这个大家一定要考虑到,这是转化数字最基本的要求嘛。
(3)溢出判断。这一点要在这里着重说一下,并为上一题(第七题)的错误作出改正。
溢出判断也是数字转化过程中要注意的很重要的一点,严谨的说,每一次算术都有溢出的可能,所以每次运算都应该进行溢出判断。当然实际编程过程中溢出毕竟只是少数情况,所以一般是不需要进行判断的,但这种转化的题目就必须要考虑了,因为这不是一个实际中的有意义的数值,而是通过机械式的转化得到的一种形式或者成为符号。
那该怎么进行溢出判断呢?是在运算前,还是运算后?是利用符号改变还是大小改变?这些情况很多,我们先来看一下溢出的本质:
我们知道(我假设你知道,不知道的话可以查看相关资料)数字在机器中,也可以说在电脑中,是用补码表示的,那数字的补码是怎么表示的呢,又是怎么溢出的呢,我们不去讨论里面的各种原理,只是来看一些实例:假设某种型的存储空间为4为二进制编码,我们知道,它一共可以表示2^4=16种不同的数字,我们就让它来表示-8—7这16个数字。-8—7的原码、反码和补码列于下表:
从这个图中可以看到,-0和+0的原码是不同的,但补码是相同的,所以“多出来“的位置正好给了-8,而没有+8。另外通过补码一列我们可以总结出这样的规律:补码从0000到1111,对应的数字为从0到7然后突变成-8然后到-1。而这里的突变点,就是我们所说的溢出点,也就是说7再加1就溢出了(本来应该是8,变成-8了),而-8再减1也会溢出(本来应该是-9变成7了)。从突变点看貌似可以通过符号的改变判断是否溢出,但仔细思考一下会发现,这只是”小的“溢出,如果7再加16呢?它还是7!所以这种方法是不对的。我们在上一题中提到了用”还原法“,当时并没有出现错误且通过了验证,但通过今天的分析我们知道,其实上次的成功只是侥幸罢了。能还原的并不一定没有溢出,当然不能还原的是一定溢出了,这个例子就不用再举了吧。那么话说回来,我们该怎么判断溢出呢?
通过分析可知,溢出是一个很随意的过程,溢出的结果也是很难捉摸。所以我们应该把溢出扼杀在摇篮里,也就是说要把”溢出后判断“的思维改为”判断要溢出“。说直白点儿,就是在运算前判断是否会溢出,有了这个思路就容易入手了,具体的语句已经写在程序里了。如果你还是会写成if(result*10>INT_MAX),那证明,怎么说呢,你要走的路还很长啊,加油吧。
明天是抗战70周年的纪念日,在此向我们的革命先烈致以敬意,也希望每个人都能珍惜来之不易的和平,珍惜来之不易的幸福生活。
相关文章推荐
- mybatis-动态SQL语句
- U-boot-2014.04移植到MINI2440(9) nor flash启动和nand flash 启动
- 单片机算法FFT
- 常用图片格式
- Topcoder SRM 664 DIV 1
- WEB前端学习之路
- 禁用mysql query cache
- java优化占用内存的方法(一)
- 【BZOJ3884】上帝与集合的正确用法
- 使用Scrapy建立一个网站抓取器
- xtion usb interface is not supported
- mybatis-SQL语句映射文件(2)增删改查、参数、缓存
- TCP协议疑难杂症全景解析
- bzoj-3771 Triple
- 【bzoj3884】【上帝与集合的正确用法】【数论】
- java并发编程第六章(6)使用线程安全可遍历映射
- iOS 播放音频的几种方法
- 修改apache日志文件路径
- UVAlive6935
- SQL中ISNULL的问题。