Для строки найдите первое внедренное вхождение целого числа
Это было задано в интервью:
Заданный в любой строке, получите мне первое вхождение целого числа.
Например
Str98, тогда он должен вернуть 98
Str87uyuy232 - он должен вернуть 87
Я дал ответ в виде цикла через строку и сравнил ее с числовыми символами, как в
if ((c >= '0') && (c <= '9'))
Затем я получил индекс числа, проанализировал его и вернул. Каким-то образом он не был убежден.
Может ли кто-нибудь поделиться наилучшим решением?
Ответы
Ответ 1
В этом решении есть две проблемы.
-
Рассмотрим тестовые примеры - есть 2 символа '8' и '7', и оба они образуют целое число 87, которое вы должны возвращать. (Это основная проблема)
-
Это несколько педантично, но целочисленное значение символа "0" не обязательно меньше значения "1", "2" и т.д. Это, вероятно, почти всегда, но я думаю, что интервьюеры как бы видеть такую заботу. Лучшим решением будет
if (Character.isDigit(c)) {...}
Существует много разных способов сделать это. Моя первая мысль:
int i = 0;
while (i < string.length() && !Character.isDigit(string.charAt(i))) i++;
int j = i;
while (j < string.length() && Character.isDigit(string.charAt(j))) j++;
return Integer.parseInt(string.substring(i, j)); // might be an off-by-1 here
Конечно, как упоминалось в комментариях, использование функции регулярного выражения в Java, вероятно, лучший способ сделать это. Но, конечно, многие интервьюеры просят вас делать подобные вещи без библиотек и т.д.
Ответ 2
С регулярным выражением это довольно просто:
String s = new String("Str87uyuy232");
Matcher matcher = Pattern.compile("\\d+").matcher(s);
matcher.find();
int i = Integer.valueOf(matcher.group());
(Спасибо Эрику Мариакеру)
Ответ 3
Использование java.util.Scanner
:
int res = new Scanner("Str87uyuy232").useDelimiter("\\D+").nextInt();
Цель Scanner
- извлечь токены из ввода (здесь a String
). Токены - это вещи, разделенные разделителями. По умолчанию разделителем символа Scanner
является пробел, а токены - это, таким образом, слова, разделенные пробелами.
Здесь я использую разделитель \D+
, что означает "все, что не является числом". Знаки, которые наш Scanner
может читать в нашей строке, это "87" и "232". Метод nextInt()
будет читать первый.
nextInt()
throws java.util.NoSuchElementException
, если нет токена для чтения. Вызовите метод hasNextInt()
перед вызовом nextInt()
, чтобы проверить, есть ли что-то для чтения.
Ответ 4
String input = "Str87uyuy232";
Matcher m = Pattern.compile("[^0-9]*([0-9]+).*").matcher(input);
if (m.matches()) {
System.out.println(m.group(1));
}
Ответ 5
На всякий случай вы хотите не-регулярное выражение и не используете другие утилиты.
здесь вы идете
public static Integer returnInteger(String s)
{
if(s== null)
return null;
else
{
char[] characters = s.toCharArray();
Integer value = null;
boolean isPrevDigit = false;
for(int i =0;i<characters.length;i++)
{
if(isPrevDigit == false)
{
if(Character.isDigit(characters[i]))
{
isPrevDigit = true;
value = Character.getNumericValue(characters[i]);
}
}
else
{
if(Character.isDigit(characters[i]))
{
value = (value*10)+ Character.getNumericValue(characters[i]);
}
else
{
break;
}
}
}
return value;
}
}
Ответ 6
Вы можете пойти и на более низкий уровень. Быстрый просмотр Значения ASCII показывает, что алфавитные символы начинаются с 65. Цифры идут от 48 до 57. При этом вы можете просто" и 'n против 127 и посмотреть, соответствует ли это значение порогу, 48 - 57.
char[] s = "Str87uyuy232".toCharArray();
String fint = "";
Boolean foundNum = false;
for (int i = 0; i < s.length; i++)
{
int test = s[i] & 127;
if (test < 58 && test > 47)
{
fint += s[i];
foundNum = true;
}
else if (foundNum)
break;
}
System.out.println(fint);
Выполнение этого не будет хорошо для реального мира (разные наборы символов), но как решение головоломки - это весело.