Консольное приложение
В этом блоке рассказывается, как написать консольное приложение для типового проекта.
Пример готового проекта можно скачать здесь.
Для выполнения задания вам необходимо
создать git
-репозиторий и добавлять в него новые коммиты в конце каждого
блока с соответствующим названием.
После выполнения типового задания вам необходимо будет переписать программу в
соответствии со своим индивидуальным заданием. Репозиторий следует опубликовать
на github
и прислать ссылку сюда.
Решим те же задачу, что и в графическом приложении:
Заданы два множества точек в вещественном пространстве. Требуется построить пересечение этих множеств.
Меню
Для начала напишем прототип меню:
import java.util.Scanner;
public class Main {
// метод выводит меню
static void menu(){
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do{
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
} while (v != 0);
}
}
С клавиатуры считывается число, пока не будет введён 0. Перед каждым запросом нового числа выводится текст меню
название коммита: menu
Добавление
Теперь добавим массивы (размера 100) координат точек первого множества и второго, а также их количество:
public class Main {
// x-координаты точек первого множества
static double[] x1 = new double[100];
// y-координаты точек первого множества
static double[] y1 = new double[100];
// кол-во точек в первом множестве
static int cnt1;
// x-координаты точек второго множества
static double[] x2 = new double[100];
// y-координаты точек второго множества
static double[] y2 = new double[100];
// кол-во точек во втором множестве
static int cnt2;
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
} while (v != 0);
}
Все добавленные массивы объявлены с помощью ключевого слова static
, как и
добавленный метод menu()
. Это обязательное требование. Всегда, когда
вы добавляете в новые переменные вне существующего метода или новые методы, они
должны объявляться с ключевым словом static
. Сказанное верно только
для данного проекта.
Теперь создадим метод добавления точек:
// метод добавления точек в качестве аргумента принимает ссылку на сканер
static void add(Scanner sc) {
// выводим подсказку
System.out.println("Введите множество точки и её координаты: int, double, double");
// читаем номер множества
int set = sc.nextInt();
// читаем x-координату
double x = sc.nextDouble();
// читаем y-координату
double y = sc.nextDouble();
// если указано первое множество
if (set == 1) {
// количество точек в первом множестве меньше 100
if (cnt1 < 100) {
// добавляем x координату в массив
x1[cnt1] = x;
// добавляем y координату в массив
y1[cnt1] = y;
// увеличиваем количество точек в первом множестве на 1
cnt1++;
System.out.printf("точка (%.3f, %.3f) добавлена во второе множество\n", x, y);
} else
System.out.println("первое множество заполнено полностью");
} else if (set == 2) { // если указано второе множество
// количество точек во втором множестве меньше 100
if (cnt2 < 100) {
// добавляем x координату в массив
x2[cnt2] = x;
// добавляем y координату в массив
y2[cnt2] = y;
// увеличиваем количество точек во втором множестве на 1
cnt2++;
System.out.printf("точка (%.3f, %.3f) добавлена во второе множество\n", x, y);
} else
System.out.println("второе множество заполнено полностью");
} else {
System.out.println(set + " - недопустимое значение множества");
}
}
Перепишем главный метод следующим образом:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
}
} while (v != 0);
}
Здесь был добавлен множественного выбора switch
.
Также дополним меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
}
название коммита: add points
Список
Теперь напишем метод вывода всех добавленных точек:
// метод вывода всех добавленных точек на экран
static void show() {
System.out.println("Точки первого множества:");
for (int i = 0; i < cnt1; i++) {
System.out.printf("%.3f, %.3f\n", x1[i], y1[i]);
}
System.out.println("Точки второго множества:");
for (int i = 0; i < cnt2; i++) {
System.out.printf("%.3f, %.3f\n", x2[i], y2[i]);
}
}
Добавим теперь вызов этого метода
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
case 2:
// запускаем вывод точек
showPoints();
break;
}
} while (v != 0);
}
Осталось дополнить меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
System.out.println("2 - список точек");
}
Запустим приложение и добавим в первое множество точки , и точку
во второе множество с помощью команд меню, а после выведем список добавленных точек (введя в главном меню
цифру 2
):
название коммита: point list
Случайные точки
Напишем сначала метод добавления случайных точек:
// добавить случайные точки
static void rnd(Scanner sc) {
// выводим подсказку
System.out.println("Введите количество случайных точек: int");
// читаем кол-во точек
int cnt = sc.nextInt();
// объект для порождения случайных чисел
Random r = new Random();
// повторяем cnt раз
for (int i = 0; i < cnt; i++) {
// если случайное логическое значение равно истине
if (r.nextBoolean()) {
// добавляем новую случайную x-координату первого множества от -5 до 5
x1[cnt1] = r.nextDouble() * 10 - 5;
// добавляем новую случайную y-координату первого множества от -5 до 5
y1[cnt1] = r.nextDouble() * 10 - 5;
// увеличиваем количество точек в первом множестве на 1
cnt1++;
} else {
// добавляем новую случайную x-координату второго множества от -5 до 5
x2[cnt2] = r.nextDouble() * 10 - 5;
// добавляем новую случайную y-координату второго множества от -5 до 5
y2[cnt2] = r.nextDouble() * 10 - 5;
// увеличиваем количество точек во втором множестве на 1
cnt2++;
}
}
System.out.println("Точки добавлены");
}
Добавим теперь вызов этого метода:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
case 2:
// запускаем вывод точек
showPoints();
break;
case 3:
// запускаем порождение случайных точек
rnd(sc);
break;
}
} while (v != 0);
}
Осталось дополнить меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
System.out.println("2 - список точек");
System.out.println("3 - добавить случайные точки");
}
Проверим работу приложения:
название коммита: random points
Сохранение
Напишем теперь метод сохранения точек в файл data.txt
. Он записывает
в файл сначала количество точек в первом множестве, потом построчно координаты
точек, потом тоже самое для второго множества
// сохранение данных в файл
static void save() {
// блок try...catch обязателен при работе с файлами
try {
// открываем файл out
PrintStream out = new PrintStream("data.txt");
// выводим количество точек в первом множестве
out.println(cnt1);
// выводим координаты точек
for (int i = 0; i < cnt1; i++) {
out.printf("%.3f %.3f\n", x1[i], y1[i]);
}
// выводим количество точек во втором множестве
out.println(cnt2);
// выводим координаты точек
for (int i = 0; i < cnt2; i++) {
out.printf("%.3f %.3f\n", x2[i], y2[i]);
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
Добавим вызов в меню:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
case 2:
// запускаем вывод точек
showPoints();
break;
case 3:
// запускаем порождение случайных точек
rnd(sc);
break;
case 4:
// сохраняем точки
save();
break;
}
} while (v != 0);
}
Также нужно добавить соответствующую строчку в меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
System.out.println("2 - список точек");
System.out.println("3 - добавить случайные точки");
System.out.println("4 - сохранить точки");
}
Запустим программу, добавим 10 случайных точек и выведем их в файл:
В папке проекта должен появиться файл data.txt
. Т.к. точки формировались случайным образом,
то содержимое файла у вас будет отличаться. Совпадать должна только сама
структура: количество точек первого множества, сами точки, количество точек второго
множества, сами точки второго множества
название коммита: save
Загрузка
Загрузка реализуется аналогично:
// чтение данных из файла
static void load() {
// блок try...catch обязателен при работе с файлами
try {
// открываем файл
Scanner sc = new Scanner(new File("data.txt"));
// вводим количество точек в первом множестве
cnt1 = sc.nextInt();
// вводим координаты точек
for (int i = 0; i < cnt1; i++) {
x1[i] = sc.nextDouble();
y1[i] = sc.nextDouble();
}
// вводим количество точек во втором множестве
cnt2 = sc.nextInt();
// вводим координаты точек
for (int i = 0; i < cnt2; i++) {
x2[i] = sc.nextDouble();
y2[i] = sc.nextDouble();
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
Дополним меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
System.out.println("2 - список точек");
System.out.println("3 - добавить случайные точки");
System.out.println("4 - сохранить точки");
System.out.println("5 - загрузить точки");
}
Также не забудьте добавить новый пункт в главном методе:
```java
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
case 2:
// запускаем вывод точек
showPoints();
break;
case 3:
// запускаем порождение случайных точек
rnd(sc);
break;
case 4:
// сохраняем точки
save();
break;
case 5:
// сохраняем точки
load();
break;
}
} while (v != 0);
}
Для тестов прочитаем сохранённые точки из файла и выведем их на консоль:
название коммита: load
Решение
Чтобы решить задачу, заполним файл data.txt
значениями вручную:
4
1,0 1,0
-1,0 1,0
1,0 2,0
2,0 1,0
2
-1,0 1,0
1,0 2,0
Пересекающихся точек две: и
Напишем метод решения задачи:
// решение задачи
static void solve() {
// массив индексов пересекающихся точек из первого множества
int[] crossedIndexes = new int[100];
// количество пересекающихся точек из первого множества
int crossedCnt = 0;
// перебираем все пары точек по одной из каждого множества
for (int i = 0; i < cnt1; i++) {
for (int j = 0; j < cnt2; j++) {
// если их координаты совпадают
if (Math.abs(x1[i] - x2[j]) < 0.001 && Math.abs(y1[i] - y2[j]) < 0.001) {
// сохраняем индекс совпадающей точки
crossedIndexes[crossedCnt] = i;
// увеличиваем количество совпавших точек на 1
crossedCnt++;
}
}
}
// выводим данные
System.out.println("Пересекающиеся точки:");
for (int i = 0; i < crossedCnt; i++) {
System.out.printf("%.1f %.1f\n", x1[crossedIndexes[i]], y1[crossedIndexes[i]]);
}
}
Дополним меню:
// метод выводит меню
static void menu() {
System.out.println("Выберите пункт меню:");
System.out.println("0 - выход");
System.out.println("1 - добавить точку");
System.out.println("2 - список точек");
System.out.println("3 - добавить случайные точки");
System.out.println("4 - сохранить точки");
System.out.println("5 - загрузить точки");
System.out.println("6 - решить задачу");
}
Также не забудьте добавить новый пункт в главном методе:
```java
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// текущий пункт меню
int v;
// пока считанное с клавиатуры число не равно 0
do {
// выводим меню
menu();
// читаем число с клавиатуры
v = sc.nextInt();
// разбираем, каким может быть введённый пункт меню
switch (v) {
case 1:
// запускаем добавление точки
add(sc);
break;
case 2:
// запускаем вывод точек
showPoints();
break;
case 3:
// запускаем порождение случайных точек
rnd(sc);
break;
case 4:
// сохраняем точки
save();
break;
case 5:
// сохраняем точки
load();
break;
case 6:
// решение задачи
solve();
break;
}
} while (v != 0);
}
Получим правильный ответ:
название коммита: solve
Задание
Пример готового проекта можно скачать здесь.
Для выполнения задания вам необходимо
создать git
-репозиторий и добавлять в него новые коммиты в конце каждого
блока с соответствующим названием.
После выполнения типового задания вам необходимо будет переписать программу в
соответствии со своим индивидуальным заданием. Репозиторий следует опубликовать
на github
и прислать ссылку сюда.