题目描述

将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0

代码一

牛客的用例是有问题的

  1. public int StrToInt(String str) {
  2. Integer res=0;
  3. try {
  4. res = new Integer(str);
  5. } catch (NumberFormatException e) {
  6. // TODO: handle exception
  7. } finally {
  8. return res;
  9. }
  10. }

代码二

正则化

  1. public int StrToInt(String str) {
  2. // \d代表[0-9] 但是要写成\\d才行。
  3. if(!str.matches("[+,-]?\\d*")) return 0;
  4. int len = str.length();
  5. int i = len-1;
  6. long res = 0; //long类型,避免溢出。不能用int
  7. while(i>=0&&str.charAt(i)>='0'&&str.charAt(i)<='9'){
  8. res += Math.pow(10,len-1-i)*(str.charAt(i)-'0');
  9. i--;
  10. }
  11. res = (str.charAt(0) == '-' ? -res : res);
  12. //溢出就返回0,用long类型的res来比较,
  13. //如果定义为int res,那再比较就没有意义了,int范围为[-2147483648,2147483647]
  14. if(res>Integer.MAX_VALUE|| res<Integer.MIN_VALUE)return 0;
  15. return (int)res;

代码三

关于数值越界:合理利用 INT_MAX/10
数值越界,即大于 2147483647,或小于 -2147483648。通过观察程序结构,我们发现,每次循环时 value 的值都会扩大10倍(乘以10),那么,我们是否就可以利用 INT_MAX/10 的值来提前一步判断是否会越界呢?这里我们以正数的越界为例进行解释:

  • 当 value > INT_MAX/10 时,说明本轮扩大10倍后,value 必将越界(超过 INT_MAX);
  • 当 value == INT_MAX/10 时,说明扩大10倍后,value 可能越界,也可能不越界,需要利用当前的加数 digit 来进行进一步的判断:当 digit > 7 时(以正数为例),越界;
  • 否则,当 value < INT_MAX/10 时,本轮循环必不越界(扩大10倍后也小于 INT_MAX);
    1. public int StrToInt(String str) {
    2. if(str==null||str.trim().equals(""))return 0;
    3. str = str.trim();
    4. char[] arr = str.toCharArray();
    5. int i=0;
    6. boolean flag=true;
    7. int res=0;
    8. if(arr[i]=='-')flag=false;
    9. if(arr[i]=='+'||arr[i]=='-')i++;
    10. while(i<arr.length) {
    11. if(arr[i]>='0'&&arr[i]<='9') {
    12. int cur = arr[i]-'0';
    13. if(flag==true&&(res>Integer.MAX_VALUE/10||res==Integer.MAX_VALUE/10&&cur>7))return 0;
    14. if(flag==false&&(res>Integer.MAX_VALUE/10||res==Integer.MAX_VALUE/10&&cur>8))return 0;
    15. res = res*10+cur;
    16. i++;
    17. }else {
    18. return 0;
    19. }
    20. }
    21. return flag? res:-res;
    22. }