/** * Implement atoi to convert a string to an integer. * Hint: Carefully consider all possible input cases. If you want a challenge, * please do not see below and ask yourself what are the possible input cases. * * Keys: Whitespaces, Additional chars, Signs, Out of range * * Requirements for atoi: * The function first discards as many whitespace characters as necessary until * the first non-whitespace character is found. Then, starting from this * character, takes an optional initial plus or minus sign followed by as many * numerical digits as possible, and interprets them as a numerical value. * * The string can contain additional characters after those that form the * integral number, which are ignored and have no effect on the behavior of * this function. * * If the first sequence of non-whitespace characters in str is not a valid * integral number, or if no such sequence exists because either str is empty * or it contains only whitespace characters, no conversion is performed. * * If no valid conversion could be performed, a zero value is returned. If the * correct value is out of the range of representable values, INT_MAX * (2147483647) or INT_MIN (-2147483648) is returned. * * Tags: Math, String */ class atoi { public static void main(String[] args) { System.out.println("MAX_VALUE: " + Integer.MAX_VALUE); System.out.println("MIN_VALUE: " + Integer.MIN_VALUE); System.out.println("2147483648: " + atoi("2147483648")); System.out.println("-2147483647: " + atoi("-2147483647")); System.out.println("-2147483648: " + atoi("-2147483648")); } /** * Whitespace, sign, out of range * Trim the unnecessary whitespaces * initialize a variable as long to store the result * use a boolean as a flag to mark whether its negative * return MAX or MIN if its out of range */ public static int atoi(String str) { /*validate input*/ if (str == null || str.length() == 0) return 0; long longRes = 0; // result can be out of range /*whitespaces*/ str = str.trim(); // remove front and trailing whitespaces /*sign*/ boolean neg = false; // is negative or not if (str.charAt(0) == '-') { neg = true; str = str.substring(1, str.length()); } else if (str.charAt(0) == '+') { str = str.substring(1, str.length()); } /*calculation*/ int i = 0; while (i < str.length()) { // calculate without sign char c = str.charAt(i); if (c >= '0' && c <= '9') { longRes = longRes * 10 + (c - '0'); } else break; // break when not a digit i++; } longRes = neg ? longRes * (-1) : longRes; // add sign /*out of range*/ if (longRes > Integer.MAX_VALUE) { return Integer.MAX_VALUE; } else if (longRes < Integer.MIN_VALUE) { return Integer.MIN_VALUE; } return (int)longRes; } /** * To deal with overflow, inspect the current number before multiplication. * If the current number is greater than 214748364, we know it is going to * overflow. On the other hand, if the current number is equal to * 214748364, we know that it will overflow only when the current digit is * greater than or equal to 8. */ private static final int maxDiv10 = Integer.MAX_VALUE / 10; public int atoi(String str) { int n = str.length(); int i = 0; while (i < n && Character.isWhitespace(str.charAt(i))) i++; int sign = 1; if (i < n && str.charAt(i) == '+') { i++; } else if (i < n && str.charAt(i) == '-') { sign = -1; i++; } int num = 0; while (i < n && Character.isDigit(str.charAt(i))) { int digit = Character.getNumericValue(str.charAt(i)); if (num > maxDiv10 || num == maxDiv10 && digit >= 8) { return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; } num = num * 10 + digit; i++; } return sign * num; } }