diff --git a/app/src/main/java/ru/project/sorting/EvenOnlyMergeSortStrategy.java b/app/src/main/java/ru/project/sorting/EvenOnlyMergeSortStrategy.java deleted file mode 100644 index 021a70e..0000000 --- a/app/src/main/java/ru/project/sorting/EvenOnlyMergeSortStrategy.java +++ /dev/null @@ -1,84 +0,0 @@ -package ru.project.sorting; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.function.ToIntFunction; -import ru.project.collection.MyList; - -public class EvenOnlyMergeSortStrategy implements SortStrategy { - - private final ToIntFunction valueExtractor; - - public EvenOnlyMergeSortStrategy(ToIntFunction valueExtractor) { - this.valueExtractor = valueExtractor; - } - - @Override - public void sort(MyList list, Comparator comparator) { - if (list == null || list.size() <= 1) { - return; - } - - List evenIndices = new ArrayList<>(); - List evenElements = new ArrayList<>(); - - for (int i = 0; i < list.size(); i++) { - T element = list.get(i); - int value = valueExtractor.applyAsInt(element); - if (value % 2 == 0) { - evenIndices.add(i); - evenElements.add(element); - } - } - - if (evenElements.size() <= 1) { - return; - } - - List sortedEven = mergeSort(evenElements, comparator); - - for (int j = 0; j < evenIndices.size(); j++) { - list.set(evenIndices.get(j), sortedEven.get(j)); - } - } - - private List mergeSort(List list, Comparator comparator) { - if (list.size() <= 1) { - return list; - } - - int mid = list.size() / 2; - List left = mergeSort(list.subList(0, mid), comparator); - List right = mergeSort(list.subList(mid, list.size()), comparator); - - return merge(left, right, comparator); - } - - private List merge(List left, List right, Comparator comparator) { - List result = new ArrayList<>(); - int i = 0, j = 0; - - while (i < left.size() && j < right.size()) { - if (comparator.compare(left.get(i), right.get(j)) <= 0) { - result.add(left.get(i)); - i++; - } else { - result.add(right.get(j)); - j++; - } - } - - while (i < left.size()) { - result.add(left.get(i)); - i++; - } - - while (j < right.size()) { - result.add(right.get(j)); - j++; - } - - return result; - } -} diff --git a/app/src/main/java/ru/project/ui/collection/CurrentCollectionMenu.java b/app/src/main/java/ru/project/ui/collection/CurrentCollectionMenu.java index f6edd36..6f72f17 100644 --- a/app/src/main/java/ru/project/ui/collection/CurrentCollectionMenu.java +++ b/app/src/main/java/ru/project/ui/collection/CurrentCollectionMenu.java @@ -7,7 +7,6 @@ import ru.project.ui.base.BaseModalWindow; import ru.project.ui.collection.sorting.SortCollectionMenu; import ru.project.ui.common.CollectionDisplayWindow; import ru.project.ui.common.CollectionFileSaveWindow; -import ru.project.ui.common.MessageWindow; public class CurrentCollectionMenu extends BaseModalWindow { @@ -15,6 +14,9 @@ public class CurrentCollectionMenu extends BaseModalWindow { private final SortCollectionMenu sortCollectionMenu; + // private final SearchCollectionMenu searchCollectionMenu; + // private final CountOccurrencesMenu countOccurrencesMenu; + public CurrentCollectionMenu(WindowBasedTextGUI gui, AppState state) { super("Меню текущей коллекции", gui); @@ -23,6 +25,9 @@ public class CurrentCollectionMenu extends BaseModalWindow { this.sortCollectionMenu = new SortCollectionMenu(gui, state); + // this.searchCollectionMenu = new SearchCollectionMenu(gui, state); + // this.countCollectionMenu = new CountOccurrencesMenu(gui, state); + ActionListBox menu = new ActionListBox(); menu.addItem("Показать коллекцию...", this::showCurrentCollection); @@ -53,12 +58,14 @@ public class CurrentCollectionMenu extends BaseModalWindow { } private void searchCollection() { - // TODO - MessageWindow.showModal(gui, "Не реализовано."); + // SearchCollectionMenu searchCollectionMenu = new SearchCollectionMenu(gui, state); + // + // searchCollectionMenu.showModal(); } private void countOccurrences() { - // TODO - MessageWindow.showModal(gui, "Не реализовано."); + // CountOccurrencesMenu countOccurrencesMenu = new CountOccurrencesMenu(gui, state); + // + // countOccurrencesMenu.showModal(); } } diff --git a/app/src/main/java/ru/project/ui/collection/sorting/SortAlgorithm.java b/app/src/main/java/ru/project/ui/collection/sorting/SortAlgorithm.java new file mode 100644 index 0000000..4f193a6 --- /dev/null +++ b/app/src/main/java/ru/project/ui/collection/sorting/SortAlgorithm.java @@ -0,0 +1,6 @@ +package ru.project.ui.collection.sorting; + +public enum SortAlgorithm { + BUBBLE, + MERGE +} diff --git a/app/src/main/java/ru/project/ui/collection/sorting/SortCollectionMenu.java b/app/src/main/java/ru/project/ui/collection/sorting/SortCollectionMenu.java index f405e2e..fc8c774 100644 --- a/app/src/main/java/ru/project/ui/collection/sorting/SortCollectionMenu.java +++ b/app/src/main/java/ru/project/ui/collection/sorting/SortCollectionMenu.java @@ -5,7 +5,16 @@ import com.googlecode.lanterna.gui2.Label; import com.googlecode.lanterna.gui2.LinearLayout; import com.googlecode.lanterna.gui2.Panel; import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import java.util.Comparator; import ru.project.model.AppState; +import ru.project.sorting.BubbleSortStrategy; +import ru.project.sorting.EvenOnlySortStrategy; +import ru.project.sorting.MergeSortStrategy; +import ru.project.sorting.SortStrategy; +import ru.project.sorting.StudentAverageGradeComparator; +import ru.project.sorting.StudentGroupComparator; +import ru.project.sorting.StudentRecordBookComparator; +import ru.project.student.Student; import ru.project.ui.base.BaseModalWindow; import ru.project.ui.common.MessageWindow; @@ -13,29 +22,37 @@ public class SortCollectionMenu extends BaseModalWindow { private final AppState state; - private final Label sortMethodLabel; + private final Label sortAlgorithmLabel; private final Label sortFieldLabel; + private final Label sortMethodLabel; - private final SortMethodSelectionWindow sortMethodSelectionWindow; private final NormalSortSettingsWindow normalSortSettingsWindow; private final ParitySortSettingsWindow paritySortSettingsWindow; + private final SortMethodSelectionWindow sortMethodSelectionWindow; + private final SortStrategySelectionWindow sortStrategySelectionWindow; - private SortMethod selectedSortMethod; + private SortAlgorithm selectedSortAlgorithm; private SortField selectedSortField; + private SortMethod selectedSortMethod; public SortCollectionMenu(WindowBasedTextGUI gui, AppState state) { super("Меню сортировки текущей коллекции", gui); this.state = state; - this.selectedSortMethod = SortMethod.NORMAL; + + this.selectedSortAlgorithm = SortAlgorithm.BUBBLE; this.selectedSortField = SortField.GROUP_NUMBER; + this.selectedSortMethod = SortMethod.NORMAL; Panel panel = new Panel(); panel.setLayoutManager(new LinearLayout()); this.sortMethodLabel = new Label("Способ сортировки: " + getSortMethodName(selectedSortMethod)); + this.sortAlgorithmLabel = + new Label("Алгоритм сортировки: " + getSortAlgorithmName(selectedSortAlgorithm)); + this.sortFieldLabel = new Label("Сортировать по: " + getSortFieldName(selectedSortMethod, selectedSortField)); @@ -52,6 +69,16 @@ public class SortCollectionMenu extends BaseModalWindow { "Сортировать по: " + getSortFieldName(selectedSortMethod, selectedSortField)); }); + this.sortStrategySelectionWindow = + new SortStrategySelectionWindow( + gui, + sortAlgorithm -> { + selectedSortAlgorithm = sortAlgorithm; + + sortAlgorithmLabel.setText( + "Алгоритм сортировки: " + getSortAlgorithmName(selectedSortAlgorithm)); + }); + this.normalSortSettingsWindow = new NormalSortSettingsWindow( gui, @@ -66,11 +93,14 @@ public class SortCollectionMenu extends BaseModalWindow { panel.addComponent(sortMethodLabel); panel.addComponent(sortFieldLabel); + panel.addComponent(sortAlgorithmLabel); - panel.addComponent(new Button("Выбрать способ сортировки", this::selectSortMethod)); + panel.addComponent(new Button("Выбрать способ сортировки...", this::selectSortMethod)); + + panel.addComponent(new Button("Выбрать алгоритм сортировки...", this::selectSortAlgorithm)); panel.addComponent( - new Button("Настроить текущий способ сортировки", this::setupCurrentSortMethod)); + new Button("Настроить текущий способ сортировки...", this::setupCurrentSortMethod)); panel.addComponent(new Button("Сортировать текущую коллекцию", this::sortCurrentCollection)); @@ -91,6 +121,10 @@ public class SortCollectionMenu extends BaseModalWindow { sortMethodSelectionWindow.showModal(); } + private void selectSortAlgorithm() { + sortStrategySelectionWindow.showModal(); + } + private void sortCurrentCollection() { if (state.getMainCollection() == null || state.getMainCollection().isEmpty()) { @@ -107,25 +141,64 @@ public class SortCollectionMenu extends BaseModalWindow { } private void sortNormally() { - // TODO - MessageWindow.showModal(gui, "Обычная сортировка не реализована."); + SortStrategy sortStrategy = getSortStrategy(); + + Comparator comparator = getSortComparator(); + + sortStrategy.sort(state.getMainCollection(), comparator); + + MessageWindow.showModal(gui, "Обычная сортировка успешно выполнена."); } private void sortByParity() { - // TODO - MessageWindow.showModal(gui, "Сортировка по чётности не реализована."); + SortStrategy sortStrategy = + new EvenOnlySortStrategy<>(getSortStrategy(), Student::getRecordBookNumber); + + Comparator comparator = new StudentRecordBookComparator(); + + sortStrategy.sort(state.getMainCollection(), comparator); + + MessageWindow.showModal(gui, "Сортировка по чётности успешно выполнена."); + } + + private SortStrategy getSortStrategy() { + return switch (selectedSortAlgorithm) { + case BUBBLE -> new BubbleSortStrategy<>(); + + case MERGE -> new MergeSortStrategy<>(); + }; + } + + private Comparator getSortComparator() { + return switch (selectedSortField) { + case GROUP_NUMBER -> new StudentGroupComparator(); + + case AVERAGE_GRADE -> new StudentAverageGradeComparator(); + + case RECORD_BOOK_NUMBER -> new StudentRecordBookComparator(); + }; } private String getSortMethodName(SortMethod sortMethod) { return switch (sortMethod) { case NORMAL -> "Обычная сортировка"; + case PARITY -> "Сортировка по чётности"; }; } + private String getSortAlgorithmName(SortAlgorithm sortAlgorithm) { + return switch (sortAlgorithm) { + case BUBBLE -> "Сортировка пузырьком"; + + case MERGE -> "Сортировка слиянием"; + }; + } + private String getSortFieldName(SortMethod sortMethod, SortField sortField) { return switch (sortMethod) { case NORMAL -> getNormalSortFieldName(sortField); + case PARITY -> "номеру зачётной книжки"; }; } @@ -133,7 +206,9 @@ public class SortCollectionMenu extends BaseModalWindow { private String getNormalSortFieldName(SortField sortField) { return switch (sortField) { case GROUP_NUMBER -> "номеру группы"; + case AVERAGE_GRADE -> "среднему баллу"; + case RECORD_BOOK_NUMBER -> "номеру зачётной книжки"; }; } diff --git a/app/src/main/java/ru/project/ui/collection/sorting/SortStrategySelectionWindow.java b/app/src/main/java/ru/project/ui/collection/sorting/SortStrategySelectionWindow.java new file mode 100644 index 0000000..2084e4e --- /dev/null +++ b/app/src/main/java/ru/project/ui/collection/sorting/SortStrategySelectionWindow.java @@ -0,0 +1,34 @@ +package ru.project.ui.collection.sorting; + +import com.googlecode.lanterna.gui2.ActionListBox; +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import java.util.function.Consumer; +import ru.project.ui.base.BaseModalWindow; + +public class SortStrategySelectionWindow extends BaseModalWindow { + + private final Consumer onSortAlgorithmSelected; + + public SortStrategySelectionWindow( + WindowBasedTextGUI gui, Consumer onSortAlgorithmSelected) { + + super("Выбор алгоритма сортировки", gui); + + this.onSortAlgorithmSelected = onSortAlgorithmSelected; + + ActionListBox menu = new ActionListBox(); + + menu.addItem("Сортировка пузырьком", () -> selectSortAlgorithm(SortAlgorithm.BUBBLE)); + + menu.addItem("Сортировка слиянием", () -> selectSortAlgorithm(SortAlgorithm.MERGE)); + + menu.addItem("Выйти", this::close); + + setComponent(menu); + } + + private void selectSortAlgorithm(SortAlgorithm sortAlgorithm) { + onSortAlgorithmSelected.accept(sortAlgorithm); + close(); + } +}