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.
Analysis
The following cases should be considered for this problem:
1. null or empty string 2. white spaces 3. +/- sign 4. calculate real value 5. handle min & max
Java Solution
public int atoi(String str) { if (str == null || str.length() < 1) return 0; // trim white spaces str = str.trim(); char flag = '+'; // check negative or positive int i = 0; if (str.charAt(0) == '-') { flag = '-'; i++; } else if (str.charAt(0) == '+') { i++; } // use double to store result double result = 0; // calculate value while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) <= '9') { result = result * 10 + (str.charAt(i) - '0'); i++; } if (flag == '-') result = -result; // handle max and min if (result > Integer.MAX_VALUE) return Integer.MAX_VALUE; if (result < Integer.MIN_VALUE) return Integer.MIN_VALUE; return (int) result; } |
public int myAtoi(String s) {
if (s == null || s.trim().length() < 1) return 0;
int _max = Integer.MAX_VALUE;
int _min = Integer.MIN_VALUE;
String res = "";
String sign = "";
s = s.replaceAll("^\s+", "");
for(int i=0; i< s.length(); i++) {
Pattern p1 = Pattern.compile("[^1234567890\+\-]");
if (p1.matcher("" + s.charAt(i)).find()) {
break;
}
if (s.charAt(i) == '-' && sign == "")
sign = "-";
else if (s.charAt(i) == '+' && sign == "")
sign = "+";
else if (s.charAt(i) == '+' && sign != "")
break;
else if (s.charAt(i) == '-' && sign != "")
break;
else
res += s.charAt(i);
//System.out.println("res; " + res);
}
if (res == "") return 0;
res = sign + res;
if (Double.valueOf(res) _max)
return _max;
else
return Integer.parseInt(res);
}
@bonsaialg:disqus ‘s answer is right. But using double is not scalable, what if the problem is changed to String to Double or String to Long or even String to BigInteger? What bigger type can you use?
Basically, trick would be to check if current value would be greater than MAX_INT..
Java’s Integer.parseInt(String s) source code // this doesn’t take ‘whitespaces’ into consideration and will throw exception.
// Here I have assumed that the number is a decimal number. So modified the original source code with radix 10.
public static int parseInt(String s) throws NumberFormatException
{
if (s == null) {
throw new NumberFormatException(“null”);
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE; // note: not Integer.MIN_VALUE
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE; // note: limit is changed here from -Integer.MAX_VALUE
i++;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
}
multmin = limit / 10;
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),10);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= 10;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
Above code will fail for ” “.
Correct solution:
public int myAtoi(String str) {
if(str == null)
return 0;
str = str.trim();
if(str.length() < 1)
return 0;
boolean isNeg = false;
int i = 0;
if(str.charAt(0) == '-') {
isNeg = true;
i++;
}
else if(str.charAt(0) == '+')
i++;
double result = 0;
while(i = '0' && str.charAt(i) Integer.MAX_VALUE)
return Integer.MAX_VALUE;
if (result < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
return (int)result;
}
Integer has range [-2147483648 , 2147483647] in Java. If the number is -214748364, the algorithm processes it as a positive integer and then change sign. The number would exceed the integer range if an integer is used.
One minor modification for prevent stackoverflowException: length check for string if(str.length()>0) {
if (str == null || str.length() 0) {
if (str.charAt(0) == '-') {
flag = '-';
i++;
} else if (str.charAt(0) == '+') {
i++;
}
}
// use double to store result
double result = 0;
// calculate value
while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) Integer.MAX_VALUE)
return Integer.MAX_VALUE;
if (result < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
return (int) result;
in next iteration when we add new integer it should come at unit’s place.
Hi article is nice, can we parsing String to int in java 8 ?
i was searching for the information then i found very good information here, it best way to convert string to int i hope this may be use full.
this is my solution to convert any string to double including fractions and + – signs
private static double checkString(String text) {
boolean isFraction = false;
int fractionIndex = -1;
boolean isSigned = false;
boolean isPostive = true;
if (text.charAt(0) == '+') {
isSigned = true;
isPostive = true;
} else if (text.charAt(0) == '-') {
isSigned = true;
isPostive = false;
}
for (int i = 0; i 57 || currentChar < 48)) {
return -1;
}
}
int start = (isSigned) ? 1 : 0;
double num;
if (!isFraction) {
return getNumber(text, start, text.length() - 1, false);
} else {
if (fractionIndex - start = start; i--) {
char currentChar = text.charAt(i);
num = num + level * (currentChar - 48);
level = level * 10;
}
if (isFraction) {
num = num / (level);
}
return num;
}
Why was double used for result?
Alternative solution.
public int myAtoi(String str) {
if (str == null || str.isEmpty()) {
return 0;
}
str = str.trim();
if (str.equals("-")) {
return 0;
}
if (str.equals("+")) {
return 0;
}
int signAdd = 0;
boolean sign = false;
long result = 0;
for (int i = 0; i 1) {
return 0;
}
}
if (c == '-') {
sign = true;
} else if (c == '+') {
sign = false;
} else if (c >= '0' && c Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
} else if (sign && result *-1 < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
}
if (sign) {
result *= -1;
}
return (int) result;
}
I guess it mean for positive numbers, eg. 42.
Obviously 42 is positive, and equals to +42, but there is no leading “+” sign.
kj;ljdaLJD
I am writing some code as said before lol. :)
Do not need this part
// handle max and min
if (result > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
if (result < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
Solution in 11 lines of Python:https://github.com/renzon/code_interview_training/blob/master/string_to_int.py
The good thing is that for integer I don’t have to worry once they are arbitrary large in Python (not arbitrary, but as long as it fit in your memory)
Really should check the string length after doing the trim(), in case it was a string of just white spaces.
I think the overflow check should be placed within for loop to attach this problem
Why are we multiplying by 10: result = result * 10 ?
well,if the str is very very very big,such as it is bigger than long,how can you handle this?
he could use :
Character.getNumericValue(str.charAt(i))
Why the sign is not always supposed to be at the beginning of the string? Please give a example? Thank you.
hi is doing that because charAt return a char so you can’t sum a char, you need a way to convert to integer one choice is that and only is charAt(pos) – 48
Bye.
why are you substracting ” to the char
?
The sign is not always supposed to be at the beginning of the string. And you also didn’t consider the situation that other character show in the string.