Сортировка строк по содержащимся числам в Java

1. Введение

В этом руководстве мы рассмотрим, как сортировать буквенно-цифровые строки по количеству, которое они содержат. Мы сосредоточимся на удалении всех нечисловых символов из строки перед сортировкой нескольких строк по оставшимся числовым символам.

Мы рассмотрим общие крайние случаи, включая пустые строки и недопустимые числа.

Наконец, мы проведем модульное тестирование нашего решения, чтобы убедиться, что оно работает должным образом.

2. Описание проблемы

Прежде чем мы начнем, нам нужно описать, чего мы хотим, чтобы наш код достиг. Для этой конкретной проблемы мы сделаем следующие предположения:

  1. Наши строки могут содержать только цифры, только буквы или их сочетание.
  2. Числа в наших строках могут быть целыми или двойными.
  3. Когда числа в строке разделены буквами, мы должны удалить букву и сжать цифры вместе. Например, 2d3 становится 23.
  4. Для простоты, когда появляется недопустимое или отсутствующее число, мы должны рассматривать их как 0.

Установив это, давайте займемся нашим решением.

3. Решение Regex

Поскольку наш первый шаг - поиск числовых шаблонов в нашей входной строке, мы можем использовать регулярные выражения, обычно известные как регулярные выражения.

Первое, что нам нужно, это наше регулярное выражение. Мы хотим сохранить все целые числа, а также десятичные точки из входной строки . Мы можем достичь нашей цели следующим образом:

String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]" String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");

Кратко объясним, что происходит:

  1. '[^]' - обозначает отрицательный набор, поэтому нацелен на любой символ, не указанный в вложенном регулярном выражении
  2. '\ d' - соответствует любому цифровому символу (0-9)
  3. '.' - соответствовать любому "." персонаж

Затем мы используем метод String.replaceAll для удаления любых символов, не указанных в нашем регулярном выражении. Делая это, мы можем гарантировать, что первые три пункта нашей цели могут быть достигнуты.

Затем нам нужно добавить некоторые условия, чтобы пустые и недопустимые строки возвращали 0, в то время как действительные строки возвращали действительный Double :

if("".equals(digitsOnly)) return 0; try { return Double.parseDouble(digitsOnly); } catch (NumberFormatException nfe) { return 0; }

Это завершает нашу логику. Все, что осталось сделать, это подключить его к компаратору, чтобы мы могли удобно сортировать списки входных строк.

Давайте создадим эффективный метод для возврата нашего компаратора откуда угодно:

public static Comparator createNaturalOrderRegexComparator() { return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber); }

4. Тест, тест, тест

Что хорошего в коде без тестов для проверки его работоспособности? Давайте настроим быстрый модульный тест, чтобы убедиться, что все работает так, как мы планировали:

List testStrings = Arrays.asList("a1", "d2.2", "b3", "d2.3.3d", "c4", "d2.f4",); // 1, 2.2, 3, 0, 4, 2.4 testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator()); List expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4"); assertEquals(expected, testStrings);

В этом модульном тесте мы собрали все запланированные сценарии. Недействительные числа, целые числа, десятичные дроби и числа, разделенные буквами, все включены в нашу переменную testStrings .

5. Заключение

В этой короткой статье мы продемонстрировали, как сортировать буквенно-цифровые строки на основе чисел в них, используя регулярные выражения, которые делают за нас тяжелую работу.

Мы обработали стандартные исключения, которые могут возникнуть при синтаксическом анализе входных строк, и протестировали различные сценарии с помощью модульного тестирования.

Как всегда, код можно найти на GitHub.