题目67:把字符串转换成整数
实现一个函数stringToInt,实现把字符串转换成整数这个功能,不能使用atoi或者其他类似的库函数。
分析
该题目主要考察的就是边界条件:
- 空字符串
if (num == null || num.length() < 1)
- 在数字范围
c >= '0' && c <= '9'
- 数据上下溢出
if (tmp > 0x8000_0000L)
- 只有正负号
- 有无正负号
if (first == '-')
else if (first == '+')
- 错误标志输出
throw new NumberFormatException(num)
思路
代码实现
public class _67 {
public static int stringToInt(String num) {
if (num == null || num.length() < 1) {
throw new NumberFormatException(num);
}
char first = num.charAt(0);
if (first == '-') {
return parseString(num, 1, false);
} else if (first == '+') {
return parseString(num, 1, true);
} else if (first <= '9' && first >= '0') {
return parseString(num, 0, true);
} else {
throw new NumberFormatException(num);
}
}
private static boolean isDigit(char c) {
return c >= '0' && c <= '9';
}
private static int parseString(String num, int index, boolean positive) {
if (index >= num.length()) {//index 开始解析的索引位置
throw new NumberFormatException(num);
}
int result;
long tmp = 0;
while (index < num.length() && isDigit(num.charAt(index))) {
tmp = tmp * 10 + num.charAt(index) - '0';//转换的关键步骤
// 保证求的得的值不超出整数的最大绝对值
if (tmp > 0x8000_0000L) {
throw new NumberFormatException(num);
}
index++;
}
if (positive) {//正数
if (tmp >= 0x8000_0000L) {
throw new NumberFormatException(num);
} else {
result = (int) tmp;
}
} else {//负号开头
if (tmp == 0x8000_0000L) {
result = 0x8000_0000;
} else {
result = (int) -tmp;
}
}//最后的长度判定,避免 1a123
if(sizeOfInt(result)+index<num.length()) {
throw new NumberFormatException(num);
}
return result;
}
//判断一个int值是几位数
final static int[] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
static int sizeOfInt(int x) {
for (int i = 0; ; i++) {//从一位数开始对比,如果比一位数大便继续对比二位数
if (x <= sizeTable[i]) {
return i + 1;
}
}
}
public static void main(String[] args) {
System.out.println("Integer.MIN_VALUE is"+Integer.parseInt(Integer.MIN_VALUE + ""));// -2147483648
System.out.println("Integer.MAX_VALUE is "+Integer.parseInt(Integer.MAX_VALUE + ""));//2147483647
System.out.println("123 -> "+stringToInt("123"));// 123
System.out.println("+123 -> "+stringToInt("+123"));// 123
System.out.println("-123 -> "+stringToInt("-123"));// -123
System.out.println("+2147483647 -> "+stringToInt("+2147483647"));// 2147483647
System.out.println("-2147483647 -> "+stringToInt("-2147483647"));// -2147483647
System.out.println("-2147483648 -> "+stringToInt("-2147483648"));// -2147483648
// System.out.println("1a123 -> "+stringToInt("1a123"));//java.lang.NumberFormatException: 1a123
// System.out.println("+2147483649 -> "+stringToInt("+2147483649"));//java.lang.NumberFormatException:+2147483649
// System.out.println("-2147483649 -> "+stringToInt("-2147483649"));//java.lang.NumberFormatException:-2147483649
// System.out.println("空字符-> "+stringToInt(""));//java.lang.NumberFormatException
// System.out.println("+2147483648 -> "+stringToInt("+2147483648"));//java.lang.NumberFormatException:+2147483648
// System.out.println("+ ->"+stringToInt("+"));//java.lang.NumberFormatException: +
// System.out.println("- ->"+stringToInt("-"));//java.lang.NumberFormatException: -
}
}
输出:(抛异常的输出见注释)
Integer.MIN_VALUE is-2147483648
Integer.MAX_VALUE is 2147483647
123 -> 123
+123 -> 123
-123 -> -123
+2147483647 -> 2147483647
-2147483647 -> -2147483647
-2147483648 -> -2147483648
一个机灵:
(res << 1) + (res << 3) 即 res*2+res*8=res*10