docs: refine EvenOnlyMergeSortStrategy specification
This commit is contained in:
+130
-77
@@ -2,148 +2,192 @@
|
|||||||
|
|
||||||
## Задача
|
## Задача
|
||||||
|
|
||||||
Дополнить существующий алгоритм сортировки слиянием специальной сортировкой, при которой элементы с чётным значением выбранного числового поля сортируются, а элементы с нечётным значением сохраняют свои исходные позиции.
|
Дополнить существующую сортировку слиянием специальной стратегией `EvenOnlyMergeSortStrategy`.
|
||||||
|
|
||||||
|
Стратегия должна сортировать только объекты, у которых выбранное числовое поле имеет чётное значение. Объекты с нечётным значением должны сохранять свои исходные позиции.
|
||||||
|
|
||||||
## Контракты
|
## Контракты
|
||||||
|
|
||||||
1. Стратегия должна реализовывать существующий интерфейс `SortStrategy<T>`.
|
1. Стратегия должна реализовывать существующий интерфейс:
|
||||||
|
|
||||||
2. Стратегия должна работать с `MyList<T>`.
|
```java
|
||||||
|
SortStrategy<T>
|
||||||
|
```
|
||||||
|
|
||||||
3. Алгоритм должен быть основан на сортировке слиянием.
|
1. Метод сортировки должен работать с:
|
||||||
|
|
||||||
4. Готовые методы сортировки Java использовать запрещено.
|
```java
|
||||||
|
MyList<T>
|
||||||
|
```
|
||||||
|
|
||||||
5. Стратегия не должна зависеть непосредственно от класса `Student`.
|
1. Для сортировки чётных элементов использовать алгоритм **Merge Sort**.
|
||||||
|
|
||||||
6. Числовое поле должно передаваться в стратегию извне в виде функции получения значения:
|
2. Готовые методы сортировки Java использовать запрещено.
|
||||||
|
|
||||||
|
3. Стратегия не должна зависеть непосредственно от класса `Student`.
|
||||||
|
|
||||||
|
4. Числовое поле передавать в стратегию извне через:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
ToIntFunction<T>
|
ToIntFunction<T>
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Функция получения числового значения должна:
|
1. Сохранить переданный `ToIntFunction<T>` во внутреннем поле стратегии.
|
||||||
|
|
||||||
- возвращать значение выбранного поля;
|
2. Для определения чётности элемента использовать:
|
||||||
- использоваться для проверки чётности;
|
|
||||||
- не содержать дополнительной логики сортировки.
|
```java
|
||||||
|
valueExtractor.applyAsInt(element)
|
||||||
2. Стратегия не должна самостоятельно выбирать поле через:
|
```
|
||||||
|
|
||||||
- `if`;
|
1. `ToIntFunction<T>` используется только для получения числового значения выбранного поля. Стратегия не должна знать, какое именно поле объекта используется.
|
||||||
- `switch`;
|
|
||||||
- проверку типа `Student`;
|
2. Для `Student` в качестве числового поля используется:
|
||||||
- прямое обращение к конкретным полям `Student`.
|
|
||||||
|
|
||||||
3. Для `Student` доступны функции получения числовых полей:
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Student::getGroupNumber
|
|
||||||
Student::getRecordBookNumber
|
Student::getRecordBookNumber
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Поле `averageGrade` не используется для определения чётности, если оно имеет нецелочисленный тип.
|
1. `getRecordBookNumber()` должен возвращать `int`.
|
||||||
|
|
||||||
## Правила сортировки
|
## Правила алгоритма
|
||||||
|
|
||||||
1. Элементы с чётным значением выбранного поля участвуют в сортировке.
|
Стратегия должна:
|
||||||
|
|
||||||
2. Элементы с нечётным значением выбранного поля не перемещаются.
|
1. Пройти по исходной `MyList<T>`.
|
||||||
|
2. Определить элементы с чётным значением, используя `ToIntFunction<T>`.
|
||||||
3. Чётные элементы должны занимать только те позиции, которые до сортировки принадлежали чётным элементам.
|
3. Запомнить позиции этих элементов.
|
||||||
|
4. Отдельно отсортировать только чётные элементы с помощью **Merge Sort** и переданного `Comparator<T>`.
|
||||||
4. Чётные элементы сортируются в натуральном порядке выбранного числового поля.
|
5. Вернуть отсортированные чётные элементы на позиции, которые занимали чётные элементы до сортировки.
|
||||||
|
6. Не изменять позиции элементов с нечётным значением.
|
||||||
5. Нечётные элементы должны остаться на своих исходных позициях.
|
7. Не изменять размер коллекции.
|
||||||
|
|
||||||
6. Количество элементов коллекции не должно изменяться.
|
|
||||||
|
|
||||||
### Пример
|
### Пример
|
||||||
|
|
||||||
Исходная коллекция:
|
Исходные значения выбранного числового поля:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[3, 8, 5, 2, 4, 7]
|
[7, 8, 3, 2, 5, 4]
|
||||||
|
```
|
||||||
|
|
||||||
|
Чётные элементы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
8, 2, 4
|
||||||
|
```
|
||||||
|
|
||||||
|
После Merge Sort:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2, 4, 8
|
||||||
```
|
```
|
||||||
|
|
||||||
Результат:
|
Результат:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[3, 2, 5, 4, 8, 7]
|
[7, 2, 3, 4, 5, 8]
|
||||||
```
|
```
|
||||||
|
|
||||||
Нечётные значения `3`, `5`, `7` остались на исходных позициях.
|
Нечётные элементы `7`, `3`, `5` остались на исходных позициях.
|
||||||
|
|
||||||
Чётные значения `8`, `2`, `4` были отсортированы по возрастанию и заняли позиции, которые изначально принадлежали чётным элементам.
|
## Пример использования
|
||||||
|
|
||||||
|
```java
|
||||||
|
SortStrategy<Student> strategy =
|
||||||
|
new EvenOnlyMergeSortStrategy<>(
|
||||||
|
Student::getRecordBookNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
strategy.sort(
|
||||||
|
students,
|
||||||
|
new StudentRecordBookComparator()
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
Стратегия получает функцию выбора числового поля извне и не содержит логики, специфичной для `Student`.
|
||||||
|
|
||||||
## Примеры тестов
|
## Примеры тестов
|
||||||
|
|
||||||
### Тест сортировки по номеру группы
|
### Обычный случай
|
||||||
|
|
||||||
Использовать `Student::getGroupNumber`:
|
Создать студентов с `recordBookNumber`:
|
||||||
|
|
||||||
```java
|
```text
|
||||||
MyList<Student> students = ...;
|
7, 8, 3, 2, 5, 4
|
||||||
|
|
||||||
SortStrategy<Student> strategy =
|
|
||||||
new EvenOnlyMergeSortStrategy<>(Student::getGroupNumber);
|
|
||||||
|
|
||||||
strategy.sort(students, new StudentGroupComparator());
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Проверить, что:
|
После сортировки ожидается:
|
||||||
|
|
||||||
- студенты с нечётным номером группы остались на исходных позициях;
|
```text
|
||||||
- студенты с чётным номером группы отсортированы по возрастанию;
|
7, 2, 3, 4, 5, 8
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверить:
|
||||||
|
|
||||||
|
- нечётные элементы сохранили свои позиции;
|
||||||
|
- чётные элементы отсортированы по возрастанию;
|
||||||
- количество элементов не изменилось.
|
- количество элементов не изменилось.
|
||||||
|
|
||||||
### Тест сортировки по номеру зачётной книжки
|
### Все значения нечётные
|
||||||
|
|
||||||
Использовать `Student::getRecordBookNumber`.
|
|
||||||
|
|
||||||
Проверить те же условия для номера зачётной книжки.
|
|
||||||
|
|
||||||
### Тест без чётных элементов
|
|
||||||
|
|
||||||
Исходные значения:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[1, 3, 5, 7]
|
1, 3, 5, 7
|
||||||
```
|
```
|
||||||
|
|
||||||
Результат должен быть идентичен исходной коллекции.
|
Ожидаемый результат:
|
||||||
|
|
||||||
### Тест без нечётных элементов
|
|
||||||
|
|
||||||
Исходные значения:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[8, 2, 6, 4]
|
1, 3, 5, 7
|
||||||
```
|
```
|
||||||
|
|
||||||
Результат:
|
### Все значения чётные
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[2, 4, 6, 8]
|
8, 2, 6, 4
|
||||||
```
|
```
|
||||||
|
|
||||||
### Тест с одним элементом
|
Ожидаемый результат:
|
||||||
|
|
||||||
Исходные значения:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[4]
|
2, 4, 6, 8
|
||||||
```
|
```
|
||||||
|
|
||||||
Результат:
|
### Один элемент
|
||||||
|
|
||||||
```text
|
```text
|
||||||
[4]
|
4
|
||||||
```
|
```
|
||||||
|
|
||||||
### Тест с пустой коллекцией
|
Ожидаемый результат:
|
||||||
|
|
||||||
Сортировка пустой коллекции не должна приводить к ошибке.
|
```text
|
||||||
|
4
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пустая коллекция
|
||||||
|
|
||||||
|
Пустая коллекция должна остаться пустой и не приводить к ошибке.
|
||||||
|
|
||||||
|
### Проверка `ToIntFunction`
|
||||||
|
|
||||||
|
Передать:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Student::getRecordBookNumber
|
||||||
|
```
|
||||||
|
|
||||||
|
и проверить, что именно `recordBookNumber` используется для определения чётности.
|
||||||
|
|
||||||
|
## Ограничения
|
||||||
|
|
||||||
|
Запрещено:
|
||||||
|
|
||||||
|
- использовать `Arrays.sort()`, `Collections.sort()`, `List.sort()` и другие готовые алгоритмы сортировки;
|
||||||
|
- перемещать элементы с нечётным значением;
|
||||||
|
- использовать отдельный алгоритм сортировки вместо Merge Sort;
|
||||||
|
- напрямую обращаться к полям `Student` внутри `EvenOnlyMergeSortStrategy`;
|
||||||
|
- выбирать поле через `if` или `switch`;
|
||||||
|
- использовать стандартные коллекции Java в качестве основной коллекции.
|
||||||
|
|
||||||
## Результат
|
## Результат
|
||||||
|
|
||||||
@@ -153,4 +197,13 @@ strategy.sort(students, new StudentGroupComparator());
|
|||||||
EvenOnlyMergeSortStrategy.java
|
EvenOnlyMergeSortStrategy.java
|
||||||
```
|
```
|
||||||
|
|
||||||
Класс должен принимать `ToIntFunction<T>` через конструктор и работать с существующими `MyList`, `SortStrategy` и компараторами.
|
Класс должен использовать:
|
||||||
|
|
||||||
|
```text
|
||||||
|
SortStrategy.java
|
||||||
|
MyList.java
|
||||||
|
ToIntFunction<T>
|
||||||
|
Comparator<T>
|
||||||
|
```
|
||||||
|
|
||||||
|
и не должен иметь зависимости от конкретного класса `Student`.
|
||||||
|
|||||||
Reference in New Issue
Block a user