博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode (8): String to Integer (atoi)
阅读量:6238 次
发布时间:2019-06-22

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

 目】LeetCode(8:  String to Integer (atoi)

URL:   https://leetcode.com/problems/string-to-integer-atoi/

【描述】

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.

【中文描述】

给一个字符串,要求转成integer。就这么一句话,不过有hint:

需要考虑各种可能的情况。

————————————————————————————————————————————————————————————

【初始思路】

题目也很直接的说,就是故意说这个模糊的,就是要考验你对于各种情况考虑的周不周全。但是个人感觉这个题设计还是有点问题。既然你不想让大家看下面的提示内容,那你就还是应该是多少说清楚,比如最明显的几种情况,字符串为空怎么处理,为null怎么处理,overflow了怎么处理。

所有这些东西,只能点开下面的详细提醒,才能看到。然后,先根据自己的理解,整理了一部分:

(1) if the string is "   " or "" or null,  should return 0 (2) str = "3124123fah1;kjf;lasdf", should return 3124123 (3) str = "      fafa123fnaf21j", should return 0 (4) str = "     -312341", should return -312341 (5) str = "ajklfla;hf;f", should return 0

然后根据这几个例子开撸。

首先,我们直接把str.trim()一下,然后情况就简单了。如果第一个字符是正负号或者数字,就接着从第二个字符开始判断。如果第一个字符直接就是特殊字符,直接return 0. 

其次,遍历是肯定的,for(int i =0;i<str.length();i++),然后charAt(i)取出每个字符

 

第三,遇到'+'或者'-'怎么处理。由于之前已经判断过第一个字符是不是正负号,所以从第二个字符开始无需再判断正负号,全部按照非法字符对待;

 

第四,遇到非数字字符怎么处理。这个相对简单一点,如果当前是第二位,那么由于第一位有可能是数字,所以需要考虑第一位的情况。

  if(第一位是数字) break;

      else { //说明第一位不是数字,那只能是正负号

             return 0;

      }

 如果当前不是第二位,那就简单,直接break就好了。

第五,剩下的可能性,就只有数字了。定义一个累积器,把遇到的数字加起来就行了。

这就够了么?

 

 

 

溢出溢出溢出!!!重要的事情说三遍!

如果溢出怎么办?还好题目要求很人性化,只要溢出就返回Integer.MAX_VALUE 或者 Integer.MIN_VALUE。那溢出的判断就简单了!

累积的过程中,给一个记位器count,每加一位数字,count++。每次在遇到数字需要累加之前,先count++,然后判断是否>=9(读者请考虑为何是9),如果<9,肯定不会溢出,累加然后continue即可。

如果 count >= 9, 就有可能溢出。我们让累加器先累加出结果,然后把结果和MAXVALUE,MINVALUE做比较,如果溢出,直接返回对应的MAXVALUE或者MINVALUE即可。

同时,由于有可能有正负号,所以在累加结果出来后,需要根据正负号情况,分情况判断。

最后,如果溢出判断通过了,循环结束了,剩下的就是输出累加结果。同样的,根据正负号判断一下,如果没有正负号,按照正数对待,输出即可。

 

【Show me the Code!!!】

1 if(str == null || str.equals("")) { 2             return 0; 3         } 4         str = str.trim(); 5         char tmp; 6         boolean signflag = false;//是否之前已经有正负号的标志位 7         long result = 0L;//用long做累加器,可以防止溢出 8         char sign = ' ';//记录正负号 9         int count = 0;//位数计数器,用来做溢出可能的判断10         if(str.charAt(0) == '+' || str.charAt(0) == '-') {11             sign = str.charAt(0);12             signflag = true;13         } else if(!Character.isDigit(str.charAt(0))) {14             return 0;15         } else { //第一位是数字16             result = str.charAt(0) - '0';17         }18         for(int i = 1; i < str.length(); i++){19             tmp = str.charAt(i);20 21             //情况1, 遇到非数字的字符,因为之前第一位检查过是否为正负号, 所以,这里如果不是数字,就要看第一位是什么22             if(!Character.isDigit(tmp)) {23                 if(i==1) {24                     //第一位后紧跟着非数字字符25                     if(Character.isDigit(str.charAt(0))){
//如果第一位是数字,那就break.26 break;27 }28 return 0;29 } else {30 //不是紧跟着出现,说明前面已经有数字31 break;32 }33 } else {
//遇到数字34 count++;35 result = result * 10 + (tmp - '0');36 if(count >= 9){
//数字位数达到10位,需要考虑溢出问题37 if(signflag && sign == '-') { //有符号,且为负38 if(result * -1 < Integer.MIN_VALUE) return Integer.MIN_VALUE;39 }40 if(signflag && sign == '+') { //有符号,且为正41 if(result > Integer.MAX_VALUE) return Integer.MAX_VALUE;42 }43 //这个可能性不能漏了,没有符号,按照正的对待44 if(!signflag && result > Integer.MAX_VALUE) {
return Integer.MAX_VALUE ;}45 }46 }47 }48 //程序走到这里,说明没有溢出,我们也累加得到了数字result, 但是result是无符号的,所以需要考虑正负号49 if(signflag && sign == '-') { //如果有符号且为负,转换符号输出50 return (int)result * -1;51 }52 if(signflag && sign == '+') { //如果有符号且为正,直接输出53 return (int)result;54 }55 return (int)result; //这种情况是捡漏的,如果无符号,走到这里,直接输出
MyAtoi

 

【反思 】

遇到这种需要考虑N多种情况的题,不要一个情况一个情况分别对待。要懂得归并,很多问题,其实合并后是一个问题。

同时,要懂总结规律。例如本题中,由于一开始的' '全都可以跳过,所以可以直接trim(),去掉他们的干扰。trim后,第一个字符要么是正负号,要么是数字才可以接受。否则直接return 0。通过trim的操作,直接在后面的循环里可以不用再考虑' '的情况,遇到非数字只需要考虑当前情况即可。

 

 

 

 

 

转载于:https://www.cnblogs.com/lupx/p/leetcode-8.html

你可能感兴趣的文章
PopupWindow弹框
查看>>
poll和select
查看>>
vim、gvim 在 windows 下中文乱码的终极解决方案
查看>>
毕业考试
查看>>
SUSE Linux Enterprise Server
查看>>
Redis学习手册(目录)
查看>>
Linux下安装搜狗拼音输入法
查看>>
Linux shell笔记整理-------不断更新中
查看>>
shell 下面运算的几种方法
查看>>
box-sizing 的作用
查看>>
MySQL学习笔记(4)
查看>>
我的友情链接
查看>>
Arrays.asList(aa).size()一道笔试题
查看>>
aggregate(聚合)
查看>>
BizTalk Server 如何发送 EDI 消息(4)
查看>>
六大云计算厂商南山论剑,收下这封英雄帖!
查看>>
tomcat内存溢出的解决方法(java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError:)...
查看>>
discuz 上传头像失败解决方法
查看>>
为域用户创建漫游用户配置文件
查看>>
设置域用户只能登陆到特定的计算机
查看>>