1. 把字符串转换成整数

写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

  1. 示例 1:
  2. 输入: "42"
  3. 输出: 42
  4. 示例 2:
  5. 输入: " -42"
  6. 输出: -42
  7. 解释: 第一个非空白字符为 '-', 它是一个负号。
  8. 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42
  9. 示例 3:
  10. 输入: "4193 with words"
  11. 输出: 4193
  12. 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
  13. 示例 4:
  14. 输入: "words and 987"
  15. 输出: 0
  16. 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
  17. 因此无法执行有效的转换。
  18. 示例 5:
  19. 输入: "-91283472332"
  20. 输出: -2147483648
  21. 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
  22. 因此返回 INT_MIN (−231)

思路:

  • 个人思路:
    • 我考虑的是将字符串扫描使用charAt()方法,将各种出现的情况进行处理,然后完成字符串拼接最后直接转换成long型,比较是否超过Integer.MAX_VALUE,或者Integer.MIN_VALUE。
    • 使用这种整体常规的整体字符串转数字的操作,对于各种不规则数字无法进行处理,比如:
      • -0000000001
      • 200000000000000000000(超过long)
      • ….
    • 那么需要了解题目本身存在的规律,重新思考。
  • 优秀解法:
    • image.png
    • 首先扫描过滤掉首部为空格的可能,然后从符号(有符号的情况下)或者数字开始。
    • 当扫描到的是‘-‘或者‘+’,那么进行记录该符号信息,最后判断这个信息来对最后结果进行处理。
    • 根据ASCII的编号,让扫描的字符-48得到的结果即是需要的数字结果。
    • 然后依次进行 原结果*10+(当前字符-48)
    • 每次计算后判断是否超过2,超过则直接进行返回对应的最大值或者最小值。
      • 注意:这里的res(返回结果是long),不然无法与2进行比较。
    • 当扫描到非数字字符或者整个字符串扫描完成,则进行最终的符号处理。
    • 返回最终结果(需要转换为int)。
      class Solution {
      public int strToInt(String str) {
         int length = str.length();
         char tmp;
         char sign = '+';
         long res = 0;
         if(length == 0) return 0;
         for(int i=0;i<length;i++){
             tmp = str.charAt(i);
             if(tmp == ' '){continue;}
             else if(tmp == '+' || tmp == '-'){
                 sign = tmp;
                 i++;
             }
             for(;i<length;i++){
                 tmp = str.charAt(i);
                 if(tmp>47 && tmp<58){
                     res = res*10 + (tmp-48);
                     if(res > Integer.MAX_VALUE){
                         if(sign=='-') return Integer.MIN_VALUE;
                         return Integer.MAX_VALUE;
                     }
                 }else break;
             }
             if(sign=='-') res*=-1;
             return (int)res;
         }
         return 0;
      }
      }