Compare commits
5 Commits
0d6dc96bc9
...
e66b14d2a0
| Author | SHA1 | Date | |
|---|---|---|---|
| e66b14d2a0 | |||
| 951d68e8f7 | |||
| 2f296d5cf4 | |||
| 0eff9f6b46 | |||
| e080a37e3f |
11
Copaci.in
Normal file
11
Copaci.in
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
10 4
|
||||||
|
Яблоко Яблоко Яблоко Яблоко
|
||||||
|
Яблоко Груша Вишня Персик
|
||||||
|
Яблоко Абрикос Вишня Слива
|
||||||
|
Яблоко Айва Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
|
Яблоко Слива Слива Слива
|
||||||
1
LinSpec.txt
Normal file
1
LinSpec.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Яблоко Яблоко Яблоко Яблоко
|
||||||
BIN
Zadachi_po_praktike.docx
Normal file
BIN
Zadachi_po_praktike.docx
Normal file
Binary file not shown.
@@ -1,6 +1,8 @@
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class DataTableModel extends AbstractTableModel {
|
public class DataTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
@@ -21,6 +23,53 @@ public class DataTableModel extends AbstractTableModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String[] getColumnNames() {
|
||||||
|
return columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Data[][] getRowData() {
|
||||||
|
return rowData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setColumnNames(String[] columnNames) {
|
||||||
|
this.columnNames = columnNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
return columnNames[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return rowData.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return columnNames.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int row, int col) {
|
||||||
|
return rowData[row][col];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int row, int column) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object value, int row, int col) {
|
||||||
|
rowData[row][col] = new Data(value.toString());
|
||||||
|
fireTableCellUpdated(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Menu action functions:
|
||||||
|
*/
|
||||||
|
|
||||||
public void addRow(int newRowPos) {
|
public void addRow(int newRowPos) {
|
||||||
int newRowCount = getRowCount() + 1;
|
int newRowCount = getRowCount() + 1;
|
||||||
Data[][] newRowData = new Data[newRowCount][getColumnCount()];
|
Data[][] newRowData = new Data[newRowCount][getColumnCount()];
|
||||||
@@ -153,6 +202,7 @@ public class DataTableModel extends AbstractTableModel {
|
|||||||
double harvest = 0;
|
double harvest = 0;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
||||||
|
// Go through all cells in table
|
||||||
for (int row = 0; row < getRowCount(); row++) {
|
for (int row = 0; row < getRowCount(); row++) {
|
||||||
for (int col = 0; col < getColumnCount(); col++) {
|
for (int col = 0; col < getColumnCount(); col++) {
|
||||||
Data cell = rowData[row][col];
|
Data cell = rowData[row][col];
|
||||||
@@ -173,46 +223,99 @@ public class DataTableModel extends AbstractTableModel {
|
|||||||
return harvest;
|
return harvest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getColumnNames() {
|
public List<Data> getTreeHarvestRating() {
|
||||||
return columnNames;
|
// First, group trees by name
|
||||||
|
HashMap<String, Double> groupHarvests = new HashMap<>();
|
||||||
|
|
||||||
|
// Go through all cells in table
|
||||||
|
for (int row = 0; row < getRowCount(); row++) {
|
||||||
|
for (int col = 0; col < getColumnCount(); col++) {
|
||||||
|
Data cell = rowData[row][col];
|
||||||
|
// Skip cells without tree names
|
||||||
|
if (cell.getTree().equals("")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Increase group harvest by harvest of this tree
|
||||||
|
if (!groupHarvests.containsKey(cell.getTree())) {
|
||||||
|
// If this is first time encountering this tree, create new group
|
||||||
|
groupHarvests.put(cell.getTree(), cell.getHarvest());
|
||||||
|
} else {
|
||||||
|
Double newValue = groupHarvests.get(cell.getTree()) + cell.getHarvest();
|
||||||
|
groupHarvests.put(cell.getTree(), newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Data[][] getRowData() {
|
// Second, use Data class to store the results
|
||||||
return rowData;
|
List<Data> harvestData = new ArrayList<>();
|
||||||
}
|
|
||||||
|
for (Map.Entry<String, Double> entry : groupHarvests.entrySet()) {
|
||||||
public void setColumnNames(String[] columnNames) {
|
Data newEntry = new Data(entry.getKey(), entry.getValue());
|
||||||
this.columnNames = columnNames;
|
harvestData.add(newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Third, sort the resulting list
|
||||||
|
harvestData.sort(new Comparator<Data>() {
|
||||||
@Override
|
@Override
|
||||||
public String getColumnName(int column) {
|
public int compare(Data o1, Data o2) {
|
||||||
return columnNames[column];
|
double h1 = o1.getHarvest();
|
||||||
|
double h2 = o2.getHarvest();
|
||||||
|
return Double.compare(h1, h2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Collections.reverse(harvestData);
|
||||||
|
|
||||||
|
return harvestData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public RectangleArea findSmallestSectorWithVariety(int variety) {
|
||||||
public int getRowCount() {
|
RectangleArea smallestArea = null;
|
||||||
return rowData.length;
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return smallestArea;
|
||||||
public int getColumnCount() {
|
|
||||||
return columnNames.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private RectangleArea getSmallestAreaWithVarietyForSpot(int x, int y, int targetVariety) {
|
||||||
public Object getValueAt(int row, int col) {
|
RectangleArea smallestArea = null;
|
||||||
return rowData[row][col];
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
if (smallestArea == null || rectangle.area < smallestArea.area) {
|
||||||
public boolean isCellEditable(int row, int column) {
|
smallestArea = rectangle;
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return smallestArea;
|
||||||
public void setValueAt(Object value, int row, int col) {
|
}
|
||||||
rowData[row][col] = new Data(value.toString());
|
|
||||||
fireTableCellUpdated(row, col);
|
private int getRectangleUniqueTreesAmount(RectangleArea rectangle) {
|
||||||
|
Set<String> 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class IndexValidator {
|
|||||||
|
|
||||||
// Error: resulting index is negative
|
// Error: resulting index is negative
|
||||||
if (inputRow <= 0) {
|
if (inputRow <= 0) {
|
||||||
String message = String.format("Невозможно нийти строчку %d: номер должен быть больше 0", inputRow);
|
String message = String.format("Невозможно найти строчку %d: номер должен быть больше 0", inputRow);
|
||||||
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, message, "Неправильный индекс строчки", JOptionPane.ERROR_MESSAGE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/MenuActionFindSmallestSector.java
Normal file
80
src/MenuActionFindSmallestSector.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/MenuActionGetHarvestPerType.java
Normal file
28
src/MenuActionGetHarvestPerType.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MenuActionGetHarvestPerType implements ActionListener {
|
||||||
|
private DataTableModel tableModel;
|
||||||
|
|
||||||
|
public MenuActionGetHarvestPerType(DataTableModel tableModel) {
|
||||||
|
this.tableModel = tableModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.out.println("Get harvest per type");
|
||||||
|
|
||||||
|
// Get sorted list of harvest per tree type
|
||||||
|
List<Data> harvestData = tableModel.getTreeHarvestRating();
|
||||||
|
|
||||||
|
// Create a string where each element is at a separate line
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
for (Data entry : harvestData) {
|
||||||
|
result.append(String.format("%s - %.3f", entry.getTree(), entry.getHarvest()));
|
||||||
|
result.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(null, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/MenuActionLinSpec.java
Normal file
53
src/MenuActionLinSpec.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MenuActionLinSpec implements ActionListener {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
DataReader dataReader = new DataReader();
|
||||||
|
String[][] treesGrid = dataReader.readTrees("Copaci.in");
|
||||||
|
|
||||||
|
int rowCount = treesGrid.length;
|
||||||
|
int colCount = treesGrid[0].length;
|
||||||
|
|
||||||
|
// Go through each row of the grid
|
||||||
|
StringBuilder outputGrid = new StringBuilder();
|
||||||
|
for (int row = 0; row < rowCount; row++) {
|
||||||
|
// Get first tree in the row. It will be compared to other elements to define if row is homogenous
|
||||||
|
String treeName = treesGrid[row][0];
|
||||||
|
boolean isHomogenous = true;
|
||||||
|
|
||||||
|
StringBuilder outputRow = new StringBuilder();
|
||||||
|
for (int col = 0; col < colCount; col++) {
|
||||||
|
// Stop execution if a tree of different type was discovered
|
||||||
|
if (!treesGrid[row][col].equals(treeName)) {
|
||||||
|
isHomogenous = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add tree to output row
|
||||||
|
outputRow.append(treesGrid[row][col]);
|
||||||
|
outputRow.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHomogenous) {
|
||||||
|
outputGrid.append(outputRow);
|
||||||
|
outputGrid.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter("LinSpec.txt"));
|
||||||
|
writer.write(outputGrid.toString());
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(null, "Копирование успешно");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,9 +58,18 @@ public class MenuBar extends JMenuBar {
|
|||||||
plumHarvestAvgItem.addActionListener(new MenuActionGetPlumHarvestAvg(tableModel));
|
plumHarvestAvgItem.addActionListener(new MenuActionGetPlumHarvestAvg(tableModel));
|
||||||
menu.add(plumHarvestAvgItem);
|
menu.add(plumHarvestAvgItem);
|
||||||
|
|
||||||
menu.add(createMockMenuItem("Общий урожай"));
|
JMenuItem harvestPerTypeItem = new JMenuItem("Общий урожай");
|
||||||
menu.add(createMockMenuItem("Lin Spec"));
|
harvestPerTypeItem.addActionListener(new MenuActionGetHarvestPerType(tableModel));
|
||||||
menu.add(createMockMenuItem("Сектор К деревьев"));
|
menu.add(harvestPerTypeItem);
|
||||||
|
|
||||||
|
JMenuItem linSpecItem = new JMenuItem("Lin Spec");
|
||||||
|
linSpecItem.addActionListener(new MenuActionLinSpec());
|
||||||
|
menu.add(linSpecItem);
|
||||||
|
|
||||||
|
JMenuItem sectorItem = new JMenuItem("Сектор K деревьев");
|
||||||
|
sectorItem.addActionListener(new MenuActionFindSmallestSector(tableModel));
|
||||||
|
menu.add(sectorItem);
|
||||||
|
|
||||||
this.add(menu);
|
this.add(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
src/RectangleArea.java
Normal file
15
src/RectangleArea.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user