diff --git a/src/DataTableModel.java b/src/DataTableModel.java index 5da36af..626a4f6 100644 --- a/src/DataTableModel.java +++ b/src/DataTableModel.java @@ -267,4 +267,55 @@ public class DataTableModel extends AbstractTableModel { return harvestData; } + + public RectangleArea findSmallestSectorWithVariety(int variety) { + RectangleArea smallestArea = null; + + for (int row = 0; row < getRowCount(); row++) { + for (int col = 0; col < getColumnCount(); col++) { + RectangleArea spotSmallestArea = getSmallestAreaWithVarietyForSpot(col, row, variety); + + if (smallestArea == null || (spotSmallestArea != null && spotSmallestArea.area < smallestArea.area)) { + smallestArea = spotSmallestArea; + } + } + } + + return smallestArea; + } + + private RectangleArea getSmallestAreaWithVarietyForSpot(int x, int y, int targetVariety) { + RectangleArea smallestArea = null; + + int maxHeight = getRowCount() - y; + int maxWidth = getColumnCount() - x; + + for (int height = 1; height <= maxHeight; height++) { + for (int width = 1; width <= maxWidth; width++) { + RectangleArea rectangle = new RectangleArea(x, y, width, height); + int uniqueTreesAmount = getRectangleUniqueTreesAmount(rectangle); + + if (uniqueTreesAmount != targetVariety) { + continue; + } + + if (smallestArea == null || rectangle.area < smallestArea.area) { + smallestArea = rectangle; + } + } + } + + return smallestArea; + } + + private int getRectangleUniqueTreesAmount(RectangleArea rectangle) { + Set uniqueTrees = new HashSet<>(); + for (int row = rectangle.y; row < rectangle.y + rectangle.height; row++) { + for (int col = rectangle.x; col < rectangle.x + rectangle.width; col++) { + uniqueTrees.add(rowData[row][col].getTree()); + } + } + + return uniqueTrees.size(); + } } diff --git a/src/IndexValidator.java b/src/IndexValidator.java index ccf8e36..82fa6ae 100644 --- a/src/IndexValidator.java +++ b/src/IndexValidator.java @@ -29,7 +29,7 @@ public class IndexValidator { // Error: resulting index is negative if (inputRow <= 0) { - String message = String.format("Невозможно нийти строчку %d: номер должен быть больше 0", inputRow); + String message = String.format("Невозможно найти строчку %d: номер должен быть больше 0", inputRow); JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE); return -1; } diff --git a/src/MenuActionFindSmallestSector.java b/src/MenuActionFindSmallestSector.java new file mode 100644 index 0000000..4dbce4d --- /dev/null +++ b/src/MenuActionFindSmallestSector.java @@ -0,0 +1,80 @@ +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class MenuActionFindSmallestSector implements ActionListener { + private DataTableModel tableModel; + + public MenuActionFindSmallestSector(DataTableModel tableModel) { + this.tableModel = tableModel; + } + + public void actionPerformed(ActionEvent e) { + System.out.println("Find smallest sector"); + + Object[] options = {"Поиск", "Отмена"}; + + JPanel panel = new JPanel(); + panel.add(new JLabel("Введите число k")); + + JTextField textField = new JTextField(10); + panel.add(textField); + + int variety = -1; + while (variety == -1) { + int result = JOptionPane.showOptionDialog( + null, + panel, + "Введите число k", + JOptionPane.YES_NO_OPTION, + JOptionPane.PLAIN_MESSAGE, + null, + options, + null + ); + + // Canceled by user + if (result == JOptionPane.CLOSED_OPTION || result == 1) { + return; + } + + int inputVariety; + // Check for validity of input data (should be a number) + try { + inputVariety = Integer.parseInt(textField.getText()); + } catch (NumberFormatException error) { + // Error: empty input field / input not a number + String message = "Пожалуйста введите правильное число"; + JOptionPane.showMessageDialog(null, message, "Неправильное число", JOptionPane.ERROR_MESSAGE); + continue; + } + + // Error: resulting number is negative + if (inputVariety <= 0) { + String message = String.format("Невозможно найти сектор с k=%d: номер должен быть больше 0", inputVariety); + JOptionPane.showMessageDialog(null, message, "Неправильное число", JOptionPane.ERROR_MESSAGE); + continue; + } + + variety = inputVariety; + } + + RectangleArea smallestSector = tableModel.findSmallestSectorWithVariety(variety); + + // Check if operation is successful + if (smallestSector != null) { + String message = String.format( + "Площадь: %d\nЛевая верхняя область: x=%d, y=%d\nПравая нижняя область: x=%d, y=%d", + smallestSector.area, + smallestSector.x + 1, + smallestSector.y + 1, + smallestSector.x + smallestSector.width, + smallestSector.y + smallestSector.height + ); + JOptionPane.showMessageDialog(null, message); + } else { + String message = String.format("Не удалось найти сектор с k=%d", variety); + JOptionPane.showMessageDialog(null, message, "Неудача", JOptionPane.ERROR_MESSAGE); + } + } +} diff --git a/src/MenuBar.java b/src/MenuBar.java index 090e16c..7f0ccde 100644 --- a/src/MenuBar.java +++ b/src/MenuBar.java @@ -66,7 +66,10 @@ public class MenuBar extends JMenuBar { linSpecItem.addActionListener(new MenuActionLinSpec()); menu.add(linSpecItem); - menu.add(createMockMenuItem("Сектор К деревьев")); + JMenuItem sectorItem = new JMenuItem("Сектор K деревьев"); + sectorItem.addActionListener(new MenuActionFindSmallestSector(tableModel)); + menu.add(sectorItem); + this.add(menu); } diff --git a/src/RectangleArea.java b/src/RectangleArea.java new file mode 100644 index 0000000..f9ef421 --- /dev/null +++ b/src/RectangleArea.java @@ -0,0 +1,15 @@ +public class RectangleArea { + public int x; + public int y; + public int width; + public int height; + public int area; + + public RectangleArea(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.area = width * height; + } +}