refactor: atoi
(#5324)
This commit is contained in:
parent
134b42c7ff
commit
046f5a4728
@ -1,76 +1,65 @@
|
|||||||
// Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer
|
|
||||||
// (similar to C/C++'s atoi function). Here is my implementation
|
|
||||||
|
|
||||||
package com.thealgorithms.strings;
|
package com.thealgorithms.strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class that provides a method to convert a string to a 32-bit signed integer (similar to C/C++'s atoi function).
|
||||||
|
*/
|
||||||
public final class MyAtoi {
|
public final class MyAtoi {
|
||||||
private MyAtoi() {
|
private MyAtoi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given string to a 32-bit signed integer.
|
||||||
|
* The conversion discards any leading whitespace characters until the first non-whitespace character is found.
|
||||||
|
* Then, it 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 number is out of the range of a 32-bit signed integer:
|
||||||
|
* - Returns {@code Integer.MAX_VALUE} if the value exceeds {@code Integer.MAX_VALUE}.
|
||||||
|
* - Returns {@code Integer.MIN_VALUE} if the value is less than {@code Integer.MIN_VALUE}.
|
||||||
|
*
|
||||||
|
* If no valid conversion could be performed, a zero is returned.
|
||||||
|
*
|
||||||
|
* @param s the string to convert
|
||||||
|
* @return the converted integer, or 0 if the string cannot be converted to a valid integer
|
||||||
|
*/
|
||||||
public static int myAtoi(String s) {
|
public static int myAtoi(String s) {
|
||||||
s = s.trim();
|
if (s == null || s.isEmpty()) {
|
||||||
char[] char1 = s.toCharArray();
|
|
||||||
String number = "";
|
|
||||||
boolean negative = false;
|
|
||||||
boolean zero = false;
|
|
||||||
boolean isDigit = false;
|
|
||||||
|
|
||||||
for (char ch : char1) {
|
|
||||||
if (Character.isDigit(ch)) {
|
|
||||||
if (number.length() > 1 && !isDigit) {
|
|
||||||
number = "0";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
isDigit = true;
|
|
||||||
if (zero) {
|
|
||||||
number = "0";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
number += ch;
|
|
||||||
}
|
|
||||||
} else if (ch == '-' && !isDigit) {
|
|
||||||
number += "0";
|
|
||||||
negative = true;
|
|
||||||
} else if (ch == '+' && !isDigit) {
|
|
||||||
number += "0";
|
|
||||||
} else if (ch == '.' && isDigit) {
|
|
||||||
break;
|
|
||||||
} else if (ch == '.') {
|
|
||||||
zero = true;
|
|
||||||
} else {
|
|
||||||
if (!isDigit) {
|
|
||||||
number = "0";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDigit) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
number = number.replaceFirst("^0+(?!$)", "");
|
s = s.trim();
|
||||||
|
int length = s.length();
|
||||||
if (number.length() > 10 && negative) {
|
if (length == 0) {
|
||||||
return -2147483648;
|
return 0;
|
||||||
} else if (number.length() > 10) {
|
|
||||||
return 2147483647;
|
|
||||||
} else if (number.length() == 10 && negative) {
|
|
||||||
double db1 = Double.parseDouble(number);
|
|
||||||
if (db1 >= 2147483648d) {
|
|
||||||
return -2147483648;
|
|
||||||
}
|
|
||||||
} else if (number.length() == 10) {
|
|
||||||
double db1 = Double.parseDouble(number);
|
|
||||||
if (db1 > (2147483647)) {
|
|
||||||
return 2147483647;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative) {
|
int index = 0;
|
||||||
return Integer.parseInt(number) * -1;
|
boolean negative = false;
|
||||||
|
|
||||||
|
// Check for the sign
|
||||||
|
if (s.charAt(index) == '-' || s.charAt(index) == '+') {
|
||||||
|
negative = s.charAt(index) == '-';
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Integer.parseInt(number);
|
int number = 0;
|
||||||
|
while (index < length) {
|
||||||
|
char ch = s.charAt(index);
|
||||||
|
if (!Character.isDigit(ch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int digit = ch - '0';
|
||||||
|
|
||||||
|
// Check for overflow
|
||||||
|
if (number > (Integer.MAX_VALUE - digit) / 10) {
|
||||||
|
return negative ? Integer.MIN_VALUE : Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
number = number * 10 + digit;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return negative ? -number : number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,41 +3,41 @@ package com.thealgorithms.strings;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
public class MyAtoiTest {
|
public class MyAtoiTest {
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void testOne() {
|
@CsvSource({"'42', 42", "' -42', -42", "'4193 with words', 4193", "'words and 987', 0", "'-91283472332', -2147483648", "'21474836460', 2147483647", "' +123', 123", "'', 0", "' ', 0", "'-2147483648', -2147483648", "'+2147483647', 2147483647", "' -0012a42', -12",
|
||||||
assertEquals(42, MyAtoi.myAtoi("42"));
|
"'9223372036854775808', 2147483647", "'-9223372036854775809', -2147483648", "'3.14159', 3", "' -0012', -12", "' 0000000000012345678', 12345678", "' -0000000000012345678', -12345678", "' +0000000000012345678', 12345678", "'0', 0", "'+0', 0", "'-0', 0"})
|
||||||
|
void
|
||||||
|
testMyAtoi(String input, int expected) {
|
||||||
|
assertEquals(expected, MyAtoi.myAtoi(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testTwo() {
|
void testNullInput() {
|
||||||
assertEquals(-42, MyAtoi.myAtoi(" -42"));
|
assertEquals(0, MyAtoi.myAtoi(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testThree() {
|
void testSinglePlus() {
|
||||||
assertEquals(4193, MyAtoi.myAtoi("4193 with words"));
|
assertEquals(0, MyAtoi.myAtoi("+"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFour() {
|
void testSingleMinus() {
|
||||||
assertEquals(0, MyAtoi.myAtoi("0"));
|
assertEquals(0, MyAtoi.myAtoi("-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFive() {
|
void testIntegerMinBoundary() {
|
||||||
assertEquals(5678, MyAtoi.myAtoi("5678"));
|
assertEquals(Integer.MIN_VALUE, MyAtoi.myAtoi("-2147483648"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSix() {
|
void testIntegerMaxBoundary() {
|
||||||
assertEquals(42, MyAtoi.myAtoi("+42"));
|
assertEquals(Integer.MAX_VALUE, MyAtoi.myAtoi("2147483647"));
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSeven() {
|
|
||||||
assertEquals(0, MyAtoi.myAtoi(" +0 "));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user