← Назад к вопросам
Преобразование строки в число без parseInt
1.2 Junior🔥 151 комментариев
#Другое#Основы Java
Условие
Напишите программу для преобразования строки в целое число без использования Integer.parseInt() и подобных методов.
Примеры
- "123" → 123
- "-456" → -456
- " 789 " → 789
- "2147483647" → 2147483647
- "abc" → выбросить исключение
Требования
- Обработайте знак (+ или -)
- Обработайте пробелы в начале и конце
- Обработайте переполнение int
- Выбросьте исключение для некорректного ввода
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Преобразование строки в целое число без parseInt()
Это классическая задача на собеседованиях, которая проверяет понимание работы с символами, обработку исключений и граничные случаи. Решение требует реализации алгоритма парсинга с нуля.
Пошаговый алгоритм
- Trim — удалить пробелы в начале и конце
- Проверка пустоты — если строка пуста, выбросить исключение
- Обработка знака — определить, положительное или отрицательное число
- Валидация символов — проверить, что все оставшиеся символы цифры
- Конвертация — перевести каждую цифру в число и накопить результат
- Проверка переполнения — убедиться, что результат не выходит за границы int
Основное решение
public class StringToInteger {
public static int stringToInteger(String str) {
if (str == null) {
throw new IllegalArgumentException("String cannot be null");
}
str = str.trim();
if (str.isEmpty()) {
throw new IllegalArgumentException("String cannot be empty");
}
int sign = 1;
int index = 0;
if (str.charAt(0) == '+' || str.charAt(0) == '-') {
if (str.charAt(0) == '-') {
sign = -1;
}
index = 1;
}
if (index == str.length()) {
throw new IllegalArgumentException("No digits found after sign");
}
int result = 0;
final int INT_MAX = Integer.MAX_VALUE;
final int INT_MIN = Integer.MIN_VALUE;
while (index < str.length()) {
char c = str.charAt(index);
if (!Character.isDigit(c)) {
throw new IllegalArgumentException(
"Invalid character at index " + index + ": " + c
);
}
int digit = c - '0';
if (sign == 1) {
if (result > INT_MAX / 10 ||
(result == INT_MAX / 10 && digit > 7)) {
throw new ArithmeticException("Integer overflow");
}
} else {
if (result > -(INT_MIN / 10) ||
(result == -(INT_MIN / 10) && digit > 8)) {
throw new ArithmeticException("Integer underflow");
}
}
result = result * 10 + digit;
index++;
}
return sign * result;
}
}
Тестирование
public class Main {
public static void main(String[] args) {
testCase("123", 123);
testCase("-456", -456);
testCase(" 789 ", 789);
testCase("0", 0);
testCase("+42", 42);
testCase("2147483647", Integer.MAX_VALUE);
testCase("-2147483648", Integer.MIN_VALUE);
testError("");
testError(" ");
testError("abc");
testError("12a34");
testError("-");
testError("+");
testError("2147483648");
testError("-2147483649");
}
private static void testCase(String input, int expected) {
try {
int result = StringToInteger.stringToInteger(input);
System.out.println("OK: '" + input + "' = " + result);
} catch (Exception e) {
System.out.println("ERROR: '" + input + "' -> " + e.getMessage());
}
}
private static void testError(String input) {
try {
int result = StringToInteger.stringToInteger(input);
System.out.println("FAIL: '" + input + "' should error but got " + result);
} catch (Exception e) {
System.out.println("OK: '" + input + "' -> " + e.getMessage());
}
}
}
Альтернативное решение с дополнительной обработкой
public class StringToIntegerV2 {
public static int stringToInteger(String str) {
if (str == null || str.isEmpty()) {
throw new IllegalArgumentException("Invalid input");
}
str = str.trim();
if (str.isEmpty()) {
throw new IllegalArgumentException("String is empty after trim");
}
int sign = 1;
int index = 0;
char firstChar = str.charAt(0);
if (firstChar == '-') {
sign = -1;
index = 1;
} else if (firstChar == '+') {
index = 1;
}
if (index >= str.length()) {
throw new IllegalArgumentException("No digits found");
}
int result = 0;
for (int i = index; i < str.length(); i++) {
char c = str.charAt(i);
if (c < '0' || c > '9') {
throw new IllegalArgumentException("Invalid digit: " + c);
}
int digit = c - '0';
int limit = Integer.MAX_VALUE / 10;
if (sign == 1) {
if (result > limit ||
(result == limit && digit > Integer.MAX_VALUE % 10)) {
throw new ArithmeticException("Result overflow");
}
} else {
if (result > -Integer.MIN_VALUE / 10 ||
(result == -Integer.MIN_VALUE / 10 &&
digit > -(Integer.MIN_VALUE % 10))) {
throw new ArithmeticException("Result underflow");
}
}
result = result * 10 + digit;
}
return sign * result;
}
}
Объяснение проверки переполнения
Неправильно (переполнение уже произошло):
result = result * 10 + digit;
if (result > Integer.MAX_VALUE) {
throw new Exception();
}
Правильно (проверяем перед умножением):
if (result > Integer.MAX_VALUE / 10 ||
(result == Integer.MAX_VALUE / 10 && digit > 7)) {
throw new Exception();
}
result = result * 10 + digit;
Почему digit > 7 при MAX_VALUE = 2147483647?
- Integer.MAX_VALUE / 10 = 214748364
- Integer.MAX_VALUE % 10 = 7
- Если result == 214748364 и приходит цифра > 7, то overflow
Сложность
- Временная сложность: O(n), где n — длина строки
- Пространственная сложность: O(1)
Ключевые моменты
- Обработка null и пустых строк
- Обработка пробелов (trim)
- Обработка знака (+ и -)
- Валидация символов (все ли это цифры)
- Проверка переполнения — самый сложный момент
- Использование Character.isDigit()
- Преобразование char в int через вычитание '0'
Это решение демонстрирует глубокое понимание работы с числами и граничными случаями.