refactor: atoi (#5324)

This commit is contained in:
Alex Klymenko 2024-08-15 10:43:47 +02:00 committed by GitHub
parent 134b42c7ff
commit 046f5a4728
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 79 deletions

View File

@ -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;
} }
} }

View File

@ -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 "));
} }
} }