Для строки найдите первое внедренное вхождение целого числа

Это было задано в интервью:

Заданный в любой строке, получите мне первое вхождение целого числа.

Например

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);

Выполнение этого не будет хорошо для реального мира (разные наборы символов), но как решение головоломки - это весело.