LeetCode-String to Integer (atoi)-My Java Solution

最近打算换工作,为了准备面试,不得不预习数据结构与算法,想了想还是刷题吧。。

言归正传,字符串转整数,核心思想非常简单,就是根据字符'0'到'9'的整型值是连续的,所以嘛只要把字符转换成整数值,再减去'0'字符的值,就能对应得到其十进制值了。也就是说:

int charValue = myChar - '0';

如果字符是'0'到'9',那么通过上述方法得到的字符整数值就是对应的0到9;如果字符是非数字值,那么得到的结果肯定就小于0或者大于9了。

解决了一个字符转换成整数,那么一个完整的字符串呢,就需要通过遍历得到每一个字符,转换成整数后再乘以其对应的权值就行了,也就是乘以10,最后求和,代码如下:

for(int i=0;i< str.length();i++){
    int charValue = str.charAt(i) - '0';
    sum = sum * 10 + charValue;
}

那么核心思想就是这么简单。但是如果你把这个直接提交到LeetCode,就会出错。因为这段代码不够健壮,许多情况都没有考虑,在某些条件下程序会报错。这也就是我写这篇文章的原因了,把要点记录下来,并最后附上源码,直接提交到LeetCode没有任何问题。

接下来分析保证算法健壮的方法:

  1. 保证输入的字符串是非空的。如果是null,那就不需要继续往下走了,直接返回0;
  2. 考虑字符串开头有一堆空格的情况。字符串可以包含非数字字符,但是程序必须能够检测到这些字符并加以处理。在这里,如果字符串开头有空格,那么就跳过这些空格,找到第一个非空格的字符;
  3. 字符串开头可以有正号或者是负号。“+”和“-”字符用来表示数字是正还是负,这无可厚非,程序应该能够容忍这两个字符,但是只能容忍一次。也就是说如果遇到“++”、“+-”、“-+”、“++-”……等等这些字符串的时候,程序应该说NO,并返回0;
  4. 字符串中可能包含其他字符。如果跳过空格了,也跳过正号或者负号了,程序希望接下来的字符必须以数字字符开始。这样的字符串“  +123”、“  +123h1”、“  -123+32”等等,都是可以接受的,返回123或者-123。但是“  +h12j”、“  +-13”等等这样的字符就不能容忍了,返回0;
  5. 考虑数值边界问题。如果字符串通过了上面4种情况的考核,那么就可以愉快的将它转换成数字了。但是这个时候又有一个陷阱,比如算法的返回值是int类型的,int类型的数据存在一个能表示的最大值和最小值,可以用Integer.MAX_VALUE和Integer.MIN_VALUE得到,比如最大值是2147483647,只能表示10位,当字符串是"9999999999"(10个9)的时候,程序执行到第9个9的时候就应该提高警惕,因为这时如果再增加一位,必然会导致溢出。特殊情况下考虑,"2147483648"这样的字符串,前9位都没有问题,但是第10位的数字是8,终究还是大了一位,可惜啊,程序只能返回2147483647。

如果考虑完上面所有情况,写出来的代码提交到LeetCode就没有问题了。不过还是挺费精力的,我是无法一下子就考虑完备,一边提交出错修改再提交再出错,最后才修改完善的。最后附上完整源码:

class Solution {
    
    public int myAtoi(String str) {
        
        int index = 0;//字符串中字符的索引
        int sum = 0;//最后的求和结果
        int factor = 1;//系数代表正和负
        int charValue = 0;//字符串中单个字符转换成的整数值
		
	//边界
        int max = Integer.MAX_VALUE;
        int min = Integer.MIN_VALUE;
        
        if(str.length() == 0){
            return 0;
        }
        
        //忽略开头的多个空格
        for(int i=0;i < str.length();i++){
            if(str.charAt(index) == ' '){
                index++;
            }else{
                break;
            }
        }
        
        //开头可以有一个‘+’或者‘-’
	//注意index每一次加一后,都有可能out of range
        if(index >= str.length()){
            return 0;
        }else if(str.charAt(index) == '-'){
            factor = -1;//-1代表负号
            index++;
        }else if(str.charAt(index) == '+'){
            index++;
        }
        
        for(;index < str.length();index++){
            charValue = str.charAt(index) - '0';
            // 跳过正负号后字符串开头不能再有非数字字符,但是后面可跟非数字字符
            if(charValue < 0 || charValue > 9){
                break;
            }
            
            // 越界处理
            if(max/10 < sum){
                return (factor == 1) ? max : min;
            }else if(max/10 == sum){
                if(charValue > 7){
                    return (factor == 1) ? max : min;
                }else{
                    sum = sum * 10 + charValue;
                }
            }else{
                sum = sum * 10 + charValue;
            }

        }
        
        return factor * sum;
        
    }
}

你可能感兴趣的:(LeetCode)