|
13 | 13 | import java.util.Set;
|
14 | 14 |
|
15 | 15 | /**
|
| 16 | + * 8. String to Integer (atoi) |
| 17 | + * |
16 | 18 | * Implement atoi to convert a string to an integer.
|
17 |
| - 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. |
18 |
| - Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. |
19 |
| -
|
20 |
| - Requirements for atoi: |
21 |
| -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. |
22 |
| -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. |
23 |
| -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. |
24 |
| -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.*/ |
25 |
| -public class _8 { |
26 |
| - public int myAtoi_clean_version(String str) { |
27 |
| - int p = 0; |
28 |
| - int result = 0; |
29 |
| - while (p < str.length() && Character.isWhitespace(str.charAt(p))) { |
30 |
| - p++; |
31 |
| - } |
32 |
| - if (p == str.length()) { |
33 |
| - return 0; |
34 |
| - } |
35 |
| - boolean negativeFlag = (str.charAt(p) == '-'); |
36 |
| - if (str.charAt(p) == '+' || str.charAt(p) == '-') { |
37 |
| - p++; |
38 |
| - } |
39 |
| - for (; p < str.length(); p++) { |
40 |
| - if (str.charAt(p) > '9' || str.charAt(p) < '0') { |
41 |
| - break; |
42 |
| - } else { |
43 |
| - int digit = str.charAt(p) - '0'; |
44 |
| - if (!negativeFlag && result > (Integer.MAX_VALUE - digit) / 10) { |
45 |
| - return Integer.MAX_VALUE; |
46 |
| - } else if (negativeFlag && result < (Integer.MIN_VALUE + digit) / 10) { |
47 |
| - return Integer.MIN_VALUE; |
48 |
| - } |
49 |
| - result = result * 10 + (negativeFlag ? -digit : digit); |
50 |
| - } |
51 |
| - } |
52 |
| - return result; |
53 |
| - } |
| 19 | + * |
| 20 | + * 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. |
| 21 | + * Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front. |
| 22 | + * |
| 23 | + * Requirements for atoi: |
| 24 | + * The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. |
| 25 | + * 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. |
| 26 | + * 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. |
| 27 | + * If the first sequence of non-whitespace characters in str is not a valid integral number, |
| 28 | + * or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. |
| 29 | + * 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.*/ |
54 | 30 |
|
55 |
| - public static void main(String... strings) { |
56 |
| - _8 test = new _8(); |
57 |
| -// String str = "2147483648"; |
58 |
| -// String str = "+-2";//a really interesting test case, you never know how stupid one's input could be like, this is to challenge your program to be more robust. It's expecting to return 0 for this case which means it's not a valid number |
59 |
| -// String str = "+"; |
60 |
| -// String str = "abc"; |
61 |
| -// String str = "1"; |
62 |
| -// String str = "-2147483648"; |
63 |
| -// String str = "++1";//I'm really amazed by OJ's test case variety, it's expecting 0 in this case |
64 |
| -// String str = "-2147483649"; |
65 |
| - String str = "9223372036854775809"; |
66 |
| - System.out.println(test.myAtoi(str)); |
67 |
| - |
68 |
| - |
69 |
| -// System.out.println(Double.parseDouble("1.2098")); |
70 |
| -// System.out.println(Integer.parseInt("123456789")); |
71 |
| - } |
72 |
| - |
73 |
| - //Eventually, made it AC'ed, lots of corner cases, but now, really felt much easier and the though process is super clear than the first time I tried to solve it which was 3~4 years ago from now. 8/9/2016 |
74 |
| - public int myAtoi(String str) { |
75 |
| - //case 1: str is greater than Integer.MAX_VALUE, return Integer.MAX_VALUE as the question states it |
| 31 | +public class _8 { |
76 | 32 |
|
77 |
| - //case 2: str is smaller than Integer.MIN_VALUE, return Integer.MIN_VALUE as the question states it |
| 33 | + public static class Solution1 { |
| 34 | + /**Eventually, made it AC'ed, lots of corner cases, but now, |
| 35 | + * really felt much easier and the though process is super clear than the first time I tried to solve it which was 3~4 years ago from now. |
| 36 | + * - 8/9/2016 |
| 37 | + * */ |
| 38 | + public int myAtoi(String str) { |
| 39 | + //case 1: str is greater than Integer.MAX_VALUE, return Integer.MAX_VALUE as the question states it |
78 | 40 |
|
79 |
| - //case 3: str contains non-numeric values |
| 41 | + //case 2: str is smaller than Integer.MIN_VALUE, return Integer.MIN_VALUE as the question states it |
80 | 42 |
|
81 |
| - //case 4: there're many leading whitespace characters which we'll have to ignore |
| 43 | + //case 3: str contains non-numeric values |
82 | 44 |
|
83 |
| - //case 5: when finding the first non-whitespace character, it could possibly be a '+' or '-' sign, after that, we parse all the consecutive numbers |
| 45 | + //case 4: there're many leading whitespace characters which we'll have to ignore |
84 | 46 |
|
85 |
| - str = str.trim();//cut off its leading and trailing whitespace characters |
86 |
| - if (str == null || str.isEmpty()) { |
87 |
| - return 0; |
88 |
| - } |
89 |
| - Set<Character> numbers = new HashSet(); |
90 |
| - for (int i = 0; i < 10; i++) { |
91 |
| - numbers.add(Character.forDigit(i, 10)); |
92 |
| - } |
| 47 | + //case 5: when finding the first non-whitespace character, it could possibly be a '+' or '-' sign, after that, we parse all the consecutive numbers |
93 | 48 |
|
94 |
| - char[] chars = str.toCharArray(); |
95 |
| - StringBuilder sb = new StringBuilder(); |
96 |
| - boolean negative; |
97 |
| - int minuSignCount = 0; |
98 |
| - int plusSignCount = 0; |
99 |
| - int i = 0; |
100 |
| - while (i < chars.length) { |
101 |
| - if (chars[i] == '-') { |
102 |
| - minuSignCount++; |
103 |
| - i++; |
104 |
| - } else if (chars[i] == '+') { |
105 |
| - plusSignCount++; |
106 |
| - i++; |
107 |
| - } else { |
108 |
| - break; |
| 49 | + str = str.trim();//cut off its leading and trailing whitespace characters |
| 50 | + if (str == null || str.isEmpty()) { |
| 51 | + return 0; |
| 52 | + } |
| 53 | + Set<Character> numbers = new HashSet(); |
| 54 | + for (int i = 0; i < 10; i++) { |
| 55 | + numbers.add(Character.forDigit(i, 10)); |
109 | 56 | }
|
110 |
| - } |
111 |
| - if ((plusSignCount > 0 && minuSignCount > 0) || minuSignCount > 1 || plusSignCount > 1) { |
112 |
| - return 0; |
113 |
| - } |
114 |
| - negative = minuSignCount % 2 != 0; |
115 |
| - if (i >= chars.length) { |
116 |
| - return 0; |
117 |
| - } |
118 | 57 |
|
119 |
| - //it might be a floating number, so consider '.' |
120 |
| - int period = 0; |
121 |
| - while (i < chars.length && numbers.contains(chars[i])) { |
122 |
| - if (chars[i] == '.') { |
123 |
| - period++; |
| 58 | + char[] chars = str.toCharArray(); |
| 59 | + StringBuilder sb = new StringBuilder(); |
| 60 | + boolean negative; |
| 61 | + int minuSignCount = 0; |
| 62 | + int plusSignCount = 0; |
| 63 | + int i = 0; |
| 64 | + while (i < chars.length) { |
| 65 | + if (chars[i] == '-') { |
| 66 | + minuSignCount++; |
| 67 | + i++; |
| 68 | + } else if (chars[i] == '+') { |
| 69 | + plusSignCount++; |
| 70 | + i++; |
| 71 | + } else { |
| 72 | + break; |
| 73 | + } |
124 | 74 | }
|
125 |
| - if (period > 1) { |
126 |
| - break; |
| 75 | + if ((plusSignCount > 0 && minuSignCount > 0) || minuSignCount > 1 || plusSignCount > 1) { |
| 76 | + return 0; |
| 77 | + } |
| 78 | + negative = minuSignCount % 2 != 0; |
| 79 | + if (i >= chars.length) { |
| 80 | + return 0; |
127 | 81 | }
|
128 |
| - sb.append(chars[i++]); |
129 |
| - } |
130 | 82 |
|
131 |
| - if (sb == null || sb.length() == 0) { |
132 |
| - return 0; |
133 |
| - } |
| 83 | + //it might be a floating number, so consider '.' |
| 84 | + int period = 0; |
| 85 | + while (i < chars.length && numbers.contains(chars[i])) { |
| 86 | + if (chars[i] == '.') { |
| 87 | + period++; |
| 88 | + } |
| 89 | + if (period > 1) { |
| 90 | + break; |
| 91 | + } |
| 92 | + sb.append(chars[i++]); |
| 93 | + } |
134 | 94 |
|
135 |
| - int result = 0; |
136 |
| - if (period > 0) { |
137 |
| - //use Double to parse |
138 |
| - try { |
139 |
| - result = (int) Double.parseDouble(sb.toString()); |
140 |
| - } catch (Exception e) { |
141 |
| - System.out.println(e); |
| 95 | + if (sb == null || sb.length() == 0) { |
| 96 | + return 0; |
142 | 97 | }
|
143 |
| - } else { |
144 |
| - //use Long to parse to handle integer overflow case |
145 |
| - long temp = 0; |
146 |
| - if (sb.length() >= Long.toString(Long.MAX_VALUE).length() && negative) { |
147 |
| - return Integer.MIN_VALUE; |
148 |
| - } else if (sb.length() >= Long.toString(Long.MAX_VALUE).length() && !negative) { |
149 |
| - return Integer.MAX_VALUE; |
150 |
| - } else { |
| 98 | + |
| 99 | + int result = 0; |
| 100 | + if (period > 0) { |
| 101 | + //use Double to parse |
151 | 102 | try {
|
152 |
| - temp = Long.parseLong(sb.toString()); |
| 103 | + result = (int) Double.parseDouble(sb.toString()); |
153 | 104 | } catch (Exception e) {
|
154 |
| - if (sb.length() >= Integer.MAX_VALUE) { |
155 |
| - result = Integer.MAX_VALUE; |
156 |
| - } |
| 105 | + System.out.println(e); |
157 | 106 | }
|
158 |
| - if (temp > (long) Integer.MAX_VALUE + 1) { |
159 |
| - if (!negative) { |
160 |
| - return Integer.MAX_VALUE; |
161 |
| - } else { |
162 |
| - return Integer.MIN_VALUE; |
163 |
| - } |
164 |
| - } else if (temp == (long) Integer.MAX_VALUE + 1 && negative) { |
| 107 | + } else { |
| 108 | + //use Long to parse to handle integer overflow case |
| 109 | + long temp = 0; |
| 110 | + if (sb.length() >= Long.toString(Long.MAX_VALUE).length() && negative) { |
165 | 111 | return Integer.MIN_VALUE;
|
166 |
| - } else if (temp == (long) Integer.MAX_VALUE + 1) { |
| 112 | + } else if (sb.length() >= Long.toString(Long.MAX_VALUE).length() && !negative) { |
167 | 113 | return Integer.MAX_VALUE;
|
168 |
| - } else if (temp < Integer.MIN_VALUE) { |
169 |
| - result = Integer.MIN_VALUE; |
170 | 114 | } else {
|
171 |
| - result = (int) temp; |
| 115 | + try { |
| 116 | + temp = Long.parseLong(sb.toString()); |
| 117 | + } catch (Exception e) { |
| 118 | + if (sb.length() >= Integer.MAX_VALUE) { |
| 119 | + result = Integer.MAX_VALUE; |
| 120 | + } |
| 121 | + } |
| 122 | + if (temp > (long) Integer.MAX_VALUE + 1) { |
| 123 | + if (!negative) { |
| 124 | + return Integer.MAX_VALUE; |
| 125 | + } else { |
| 126 | + return Integer.MIN_VALUE; |
| 127 | + } |
| 128 | + } else if (temp == (long) Integer.MAX_VALUE + 1 && negative) { |
| 129 | + return Integer.MIN_VALUE; |
| 130 | + } else if (temp == (long) Integer.MAX_VALUE + 1) { |
| 131 | + return Integer.MAX_VALUE; |
| 132 | + } else if (temp < Integer.MIN_VALUE) { |
| 133 | + result = Integer.MIN_VALUE; |
| 134 | + } else { |
| 135 | + result = (int) temp; |
| 136 | + } |
172 | 137 | }
|
173 | 138 | }
|
| 139 | + |
| 140 | + if (negative) { |
| 141 | + result = -result; |
| 142 | + } |
| 143 | + return result; |
174 | 144 | }
|
| 145 | + } |
175 | 146 |
|
176 |
| - if (negative) { |
177 |
| - result = -result; |
| 147 | + public static class Solution2 { |
| 148 | + public int myAtoi(String str) { |
| 149 | + int p = 0; |
| 150 | + int result = 0; |
| 151 | + while (p < str.length() && Character.isWhitespace(str.charAt(p))) { |
| 152 | + p++; |
| 153 | + } |
| 154 | + if (p == str.length()) { |
| 155 | + return 0; |
| 156 | + } |
| 157 | + boolean negativeFlag = (str.charAt(p) == '-'); |
| 158 | + if (str.charAt(p) == '+' || str.charAt(p) == '-') { |
| 159 | + p++; |
| 160 | + } |
| 161 | + for (; p < str.length(); p++) { |
| 162 | + if (str.charAt(p) > '9' || str.charAt(p) < '0') { |
| 163 | + break; |
| 164 | + } else { |
| 165 | + int digit = str.charAt(p) - '0'; |
| 166 | + if (!negativeFlag && result > (Integer.MAX_VALUE - digit) / 10) { |
| 167 | + return Integer.MAX_VALUE; |
| 168 | + } else if (negativeFlag && result < (Integer.MIN_VALUE + digit) / 10) { |
| 169 | + return Integer.MIN_VALUE; |
| 170 | + } |
| 171 | + result = result * 10 + (negativeFlag ? -digit : digit); |
| 172 | + } |
| 173 | + } |
| 174 | + return result; |
178 | 175 | }
|
179 |
| - return result; |
180 | 176 | }
|
| 177 | + |
181 | 178 | }
|
0 commit comments