题目描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0
输入描述:
输入一个字符串,包括数字字母符号,可以为空
输出描述:
如果是合法的数值表达则返回该数字,否则返回0
代码一
牛客的用例是有问题的
public int StrToInt(String str) {
Integer res=0;
try {
res = new Integer(str);
} catch (NumberFormatException e) {
// TODO: handle exception
} finally {
return res;
}
}
代码二
正则化
public int StrToInt(String str) {
// \d代表[0-9] 但是要写成\\d才行。
if(!str.matches("[+,-]?\\d*")) return 0;
int len = str.length();
int i = len-1;
long res = 0; //long类型,避免溢出。不能用int
while(i>=0&&str.charAt(i)>='0'&&str.charAt(i)<='9'){
res += Math.pow(10,len-1-i)*(str.charAt(i)-'0');
i--;
}
res = (str.charAt(0) == '-' ? -res : res);
//溢出就返回0,用long类型的res来比较,
//如果定义为int res,那再比较就没有意义了,int范围为[-2147483648,2147483647]
if(res>Integer.MAX_VALUE|| res<Integer.MIN_VALUE)return 0;
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);
public int StrToInt(String str) {
if(str==null||str.trim().equals(""))return 0;
str = str.trim();
char[] arr = str.toCharArray();
int i=0;
boolean flag=true;
int res=0;
if(arr[i]=='-')flag=false;
if(arr[i]=='+'||arr[i]=='-')i++;
while(i<arr.length) {
if(arr[i]>='0'&&arr[i]<='9') {
int cur = arr[i]-'0';
if(flag==true&&(res>Integer.MAX_VALUE/10||res==Integer.MAX_VALUE/10&&cur>7))return 0;
if(flag==false&&(res>Integer.MAX_VALUE/10||res==Integer.MAX_VALUE/10&&cur>8))return 0;
res = res*10+cur;
i++;
}else {
return 0;
}
}
return flag? res:-res;
}