atoi是c/c++的库函数,用于将字符串类型转为int类型,这是一个经常出现在面试中的问题,我觉得这道题可简单也可复杂,关键看面试官的发挥。
先看一个最简单的实现,这个实现应该要快速能够写出来,因为这是最基本的实现,这通常也不会是面试官期望的最终答案。
1public class Main {
2
3 public static int atoi(String str) {
4 int result = 0;
5 for (int i = 0; i < str.length(); i++) {
6 result = result * 10 + (str.charAt(i) - '0');
7 }
8 return result;
9 }
10
11 public static void main(String[] args) {
12 System.out.println(atoi("0"));
13 System.out.println(atoi("10"));
14 System.out.println(atoi("123"));
15 }
16}
很容易看出来,上面的实现有很多问题,首先是没有处理异常情况,比如说字符串是null,或者包含非数字字符,不支持负数等等,下面再写一个能够支持负数,并且有异常处理的逻辑的实现。
1public class Main {
2
3 public static int atoi(String str) {
4 if (str == null || str.isEmpty()) {
5 throw new NumberFormatException("The str is null or empty.");
6 }
7 char firstChar = str.charAt(0);
8 boolean negative = false;
9 int i = 0;
10 if (firstChar == '-') {
11 negative = true;
12 i++;
13 }
14 int result = 0;
15 for (; i < str.length(); i++) {
16 char ch = str.charAt(i);
17 int value = ch - '0';
18 if (value < 0 || value > 9) {
19 throw new NumberFormatException("The str '" + str + "' contains invalid character.");
20 }
21 result = result * 10 + value;
22 }
23 return negative ? -result : result;
24 }
25
26 public static void main(String[] args) {
27 System.out.println(atoi("0"));
28 System.out.println(atoi("-10"));
29 System.out.println(atoi("123"));
30 System.out.println(atoi("-1 23"));
31 }
32}
33
现在看起来好多了,但是还有一个问题没有处理,那就是溢出,整型是有范围的,如果传入的字符串转为数字会超过整型的范围,我们应该抛出异常,而不是返回错误结果。这里有两个小技巧,一是我们需要在溢出的前一次进位的时候判断是否可能溢出,二是为了统一处理正数和负数的情况,在计算过程中我们会统一使用负数,因为使用-Integer.MIN_VALUE作为判断的时候会溢出,如果是正负数分开处理就不用考虑这个问题了。
1public class Main {
2
3 public static int atoi(String str) {
4 if (str == null || str.isEmpty()) {
5 throw new NumberFormatException("The str is null or empty.");
6 }
7 char firstChar = str.charAt(0);
8 int limit = -Integer.MAX_VALUE;
9 boolean negative = false;
10 int i = 0;
11 if (firstChar == '-') {
12 negative = true;
13 limit = Integer.MIN_VALUE;
14 i++;
15 }
16 int min = limit / 10;//在进位前判断,所以除以10,相对于退1位
17 int result = 0;
18 for (; i < str.length(); i++) {
19 char ch = str.charAt(i);
20 int value = ch - '0';
21 if (value < 0 || value > 9) {
22 throw new NumberFormatException("The str '" + str + "' contains invalid character.");
23 }
24 //进位前判断是否溢出
25 if (result < min) {
26 throw new NumberFormatException("The transformed number may overflow");
27 }
28 result *= 10;
29 //拼尾数前判断是否溢出
30 if (result < limit + value) {
31 throw new NumberFormatException("The transformed number may overflow");
32 }
33 result -= value;
34 }
35 return negative ? result : -result;
36 }
37
38 public static void main(String[] args) {
39 System.out.println(atoi(String.valueOf(Integer.MIN_VALUE)));
40 System.out.println(atoi(String.valueOf(Integer.MAX_VALUE)));
41 }
42}