Рубрики
Без рубрики

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

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

Автор оригинала: Sam Millington.

1. введение

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

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

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

2. Изложение проблемы

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

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

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

3. Решение Регулярных Выражений

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

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

String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]"

String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");

Давайте вкратце объясним, что происходит:

  1. ‘[^ ]’ – обозначает отрицаемый набор, поэтому нацеливается на любой символ, не указанный в прилагаемом регулярном выражении
  2. ‘\d’ – соответствует любому значному символу (0 – 9)
  3. ‘.’ – соответствует любому символу “.”

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

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

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

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

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

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

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

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