题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0


比如+2147483647,就是有效的2147483647。而1a33就是无效的,因为有个a。
  这道题对跨行过来的不太友好,需要一些编码的基础知识,就很难受。而且本题的边界需要考虑的比较详细(例如null、空字符串、带有正负号、字符不是数字、溢出等等)。我将按照某个通过测试的代码,分析整个解题思路。

思路:首先什么边界都不考虑,用最简单的来思考,就是字符串123转换成数字123,ASCII码中48~57为0到9十个阿拉伯数字。所以,当字符1要转换成数字1时,需要将字符1转换成ASCII码翻译出的数字再减去48,才是我们要的解。注意,这里可以判断其他字符,如果换算之后的数字不在0到9,就说明是其他字符,就可以结束了。针对这一步骤,应该可以写出如下几行核心代码:

//对于字符串中第i位元素的处理
                int a=(int) (chars[i]-'0');
                if(a<0 || a>9){//减去48后的数字,必须在0到9之间才有效(其他字符就不行)
                    return 0;

  然后就是对于整个串的处理。对于正数,求得的数字应该做加法,如果给出的数是负数,那么在换算过来后,应当做减法。所以可以看到,此时用一个boolean变量来记录正负非常合适。因为字符串的某一个字符对应的可能是一个百位,千位上的数,所以在比较每一个i位置的字符时,都需要进行相应的乘10运算。

//这个minus用来判断正负号
 num= (minus==false) ? num*10+a : num*10-a;

  既然选择了设置boolean变量,就应该添加对应的判断条件,比如chars[i]=='+',chars[i]=='-'。并在判断过后改写相应的boolean变量。
  至此为止,将上述过程合并后,对于我们应该来说,就完成了所有核心的部分,接下来,我们需要考虑边界情况。
  字符串为null,字符串长度为0,以及字符串太长,从而超出int型的范围,这几个特殊的边界考虑清楚即可(其他字符和正负号在核心代码部分解决)。字符串为null,字符串长度为0这两种情况在进入循环判断前就应该判断,而溢出就必须在换算过后进行判断。

写法:

public class Solution {
    public int StrToInt(String str) {       
        if(str == null || str.length()<=0)
            return 0;
        char[] chars = str.toCharArray();
        long num=0;  //先用long来存储,以防止越界。换算出来的数可能整型溢出
        boolean minus=false;
        for(int i=0; i<chars.length; i++){
            if(i==0 && chars[i]=='-'){
                minus=true;
            }else if(i==0 && chars[i]=='+'){
                minus=false;
            }else{
                int a=(int) (chars[i]-'0');
                if(a<0 || a>9){
                    return 0;
                }
                num= (minus==false) ? num*10+a : num*10-a;

                if((!minus && num>Integer.MAX_VALUE)//Integer.MAX_VALUE  0x7FFFFFFF
                   ||(minus && num<Integer.MIN_VALUE)){//Integer.MIN_VALUE  0x80000000
                    return 0;
                }
            }
        }
        return (int)num;
    }
}

小结:应该是把所有的情况都考虑了吧,我编码这部分的知识非常薄弱,如果有没有考虑完整的部分,希望大家能批评指正。