Нужна реализации задания + проверка кода [закрыт]

95
24 мая 2019, 09:20

В общем, есть задание: Напишите консольную программу, которая составляет 5-ти дневное расписание занятий для одной группы на основе введенных предметов и соответственно для каждого предмета - академических часов в неделю. При условии что максимальное количество пар в день - 4. ( 2 академических часа = 1 пара )

Проверьте пожалуйста по возможности уже существующий код на наличия каких-то ошибок в плане реализации и может советы какие-то, ну и помощь нужна именно в составлении 5-ти дневного расписания занятий, а то уже всю голову себе сломал, ну не могу найти отличное решение, нужен какой-то алгоритм составления расписания, немного о коде могу рассказать: Есть два массива, в одном название предмета, в другом, в соответствии с первым по номерам элемента([0] - [0] т.д.), число пар которые должны быть проведены за неделю(5 дней), проверку на соответствие реализовал, чтобы до момента формирования расписания дошли только корректные данные. =)

package auto;
import java.util.Scanner;
import java.io.*;
import static java.lang.Math.*;
public class Auto 
{
    public static void main(String[] args) throws IOException 
    {
        Scanner scan = new Scanner(System.in);
        System.out.println("Напишите консольную программу, которая составляет 5-ти дневное расписание занятий для одной группы на основе введенных предметов и соответственно для каждого предмета - академических часов в неделю. \nПри условии что максимальное количество пар в день - 4. ( 2 академических часа = 1 пара )");
        System.out.print("Введите количество предметов = ");
        int pars = scan.nextInt();
        if(pars > 10 || pars <= 0) 
        {
            System.out.println("Введенные данные не корректны. Максимальное количество предметов равно 10, минимальное количество должно быть больше нуля. ");
            System.out.println("Хотите ввести еще раз? 1 - да, 0 - нет. ");
            int ch = scan.nextInt();
            switch(ch) 
            {
                case 1: System.out.println("Ошибка..."); // Тут должен быть перезапуск программы, еще не дошел, не знаю как...
                default: System.exit(0);
            }
        }
        String par[] = new String[pars];
        zap(pars, par);  
        int akadem[] = new int[pars];
        akad(pars, akadem, par);
        System.out.println("Все введенные данные корректны.");
        for(int u = 0; u < pars; u++) {
            System.out.println("Предмет " + par[u] + ". Количество пар " + akadem[u]);
        }

    }

    // Заполнение массива данными по предметам
    public static int zap(int pars, String par[]) 
    {
        Scanner scan = new Scanner(System.in);
        for(int i = 0; i < pars; i++)
        {
            System.out.println("Введите название предмета №" + (i+1) + ": ");
            String inp = scan.nextLine();
            par[i] = inp;
        }
        return 0;
    }
    // Заполнение массива данными по академических часах.
    public static void akad(int pars, int akadem[], String par[]) 
    {
        Scanner scan = new Scanner(System.in);
        int y = 0;
        while(y < pars) 
        {
            for(int x = 0; x < pars; x++) 
            {
                System.out.println("Количество академических часов для предмета: " + par[x]);
                int g = scan.nextInt();
                if(g%2 == 1) { // 2 академических часа = 1 пара, в массив вношу исключительно количество пар.
                    System.out.println("Вы ввели не парное количество часов, было совершено округление к ближайшему числу.");
                    double gh = floor(g/2);
                    int h = (int)gh;
                    akadem[y] = h;
                }
                else if(g%2 == 0) {
                    int gh = g/2; 
                    akadem[y] = gh;
                }
                y += 1;
            }
        }
        int n = 0, kilk = 0;
        while(n < akadem.length) { // Проверка, не равняется ли количество пар в массиве больше 20, так как по условию в день нельзя больше 4 пары, 4*5 = 20.
            kilk += akadem[n];
            n += 1;
        }
        if (kilk > 20) { 
            System.out.println("Количество пар на неделю = " + kilk + ". Максимальное количество пар равняется 20. \nПри условии что в день разрешено не более 4 пар.\nВведенные данные не согласуются с условием.");
            System.exit(0);
        } 
    }
    // Перезапуск приложения
    public void restartApplication()
    {
    }
}
Answer 1

Хорошая задача, но мне не хочется пытаться оптимизировать имеющийся код. Тут можно (и наверно нужно) применять коллекции. Поэтому давайте попробуем сделать реализацию с нуля.

Итак, первое - это составление учебного плана. В нем должны быть предметы и количество занятий (пусть это будут пары). Для хранения подобной информации лучше всего подходит структура данных называемая карта. А то что нужно реализовать в общем случае называется CRUD - создание и редактирование данных. Ключом карты будет название предмета, а значением - количество пар в неделю.

    // вместо сканнера
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    //карта учебного плана
    Map<String, Integer> syllabus = new HashMap<>();
    // читаем строки с консоли
    while (true) {
        if (syllabus.isEmpty()) {
            System.out.println("Учебный план пуст");
        } else {
            System.out.println("\nУчебный план:");
            for (String subject : syllabus.keySet()) {
                System.out.println(subject + " " + syllabus.get(subject));
            }
            System.out.println();
        }
        System.out.println("Введите название предмета и количество часов через пробел");
        String msg = reader.readLine();
        if (msg.equals("составить расписание")) break;
        String[] split = msg.split(" ");
        String subject = split[0];  
        int value = Integer.parseInt(split[1]); // тут нужно обработать ошибку парсинга
        syllabus.put(subject, value);
    }
    reader.close();

Такой примитивный круд без D. Вы можете вводить названия и объем новых предметов и изменять объем уже имеющихся в учебном плане. Вводить и редактировать предметы можно вечно, пока не будет введена фраза "составить расписание". После этого мы вываливаемся из редактирования учебного плана и переходим к составлению расписания.

Что нам для этого нужно? Еще одна карта, в которой ключами будут дни недели, а значениями - списки занятий. Собственно

Map<String, List<String>> schedule = new HashMap<>();

Чтобы заполнить ее днями недели нужен список дней недели

    List<String> week = new ArrayList<>();
    week.add("понедельник");
    week.add("вторник");
    week.add("среда");
    week.add("четверг");
    week.add("пятница");

В карте ключи хранятся в рандомном порядке, поэтому дни недели лучше иметь отдельным упорядоченным списком. Это нам потом понадобится для вывода расписания. Заполняем карту:

    for (String day : week) {
        schedule.put(day, new ArrayList<String>());
    }

Теперь у нас есть карта с днями недели, в которой лежат пустые списки занятий. Списки надо как то заполнить. Проще всего сначала сложить все имеющиеся занятия в какую то отдельную коллекцию

    List<String> lessonsList = new ArrayList<>();
    for (String subject : syllabus.keySet()) {
        for (int i = 0; i < syllabus.get(subject); i++) {
            lessonsList.add(subject);
        }
    }

У нас появился список всех занятий. Дальше можно просто брать каждый день недели и перекладывать занятия из полного списка в список каждого отдельного дня.

    while (lessonsList.size() > 0) {
        for (String day : schedule.keySet()) {
            if (!lessonsList.isEmpty()) {
                // добавляем занятие в список дня, удаляя из полного списка
                schedule.get(day).add(lessonsList.remove(copy.size() - 1));
                // перетряхиваем расписание чтобы оно не было однообразным
                Collections.shuffle(schedule.get(day));
            }
        }
    }

Расписание готово, осталось насладиться результатом. Выводи расписание по дням недели, ключи берем не из самой карты, а из списка, чтобы дни недели шли по порядку:

    System.out.println("Расписание на неделю: \n");
    for (String day : week) {
        System.out.println(day + ":");
        for (String subject : schedule.get(day)) {
            System.out.println(subject);
        }
        System.out.println();
    }

При перекладывании занятий из полного списка в списки отдельных дней можно реализовать любую логику. Здесь каждый день берет себе одно занятие, потом следующий... когда дни заканчиваются цикл повторяется. Но это только вариант.

Наверно это и было сутью вопроса как раскидать занятия по дням недели. С помощью коллекций можно вот так - перекладыванием.

Не реализована обработка некорректного введения информации о занятиях в учебный план и проверка что их количество не превышает количество занятий в неделю. Пары можно заменить академическими часами. Думаю это не сложно.

Можно еще добавить какие либо проверки для отдельных дней недели например чтобы одинаковые занятия шли подряд, или наоборот не шли... На что хватит фантазии.

READ ALSO
Java получение дат прошлой недели

Java получение дат прошлой недели

Подскажите, пожалуйста, как в java правильно и просто получить список будних дней между датами? С например, на вход в метод кидаем Date(1211

76
Как передать интент в уже запущенный сервис?

Как передать интент в уже запущенный сервис?

Нашел код запуска сервиса и отправки значения в него:

114
Обновление данных на JFrame

Обновление данных на JFrame

Делаю программу для взаимодействия с базой данныхРисую достаточно примитивную форму

109
Получение списка из ObjectInputStream

Получение списка из ObjectInputStream

Есть метод,который отправляет серверу команду, в ответ сервер отправляет список автомобилейМетод:

101