2. Обоснование выбранных методов и алгоритмов
Для создания структуры данных будем использовать классы. Необходимо будет создать класс, содержащий всю необходимую информацию о рейсе. Эту информацию будем хранить в бинарном файле. Использование для этих целей форматированного файлового ввода/вывода нецелесообразно: дополнительные трудности при обработке файла при большом количестве данных.
Обращаться к файлу необходимо будет два раза. Первый раз при запуске программы - для чтения информации из файла в оперативную память, второй - при закрытии ее для сохранения данных в файле. Поэтому необходимо использовать объекты ifstream и ofstream, а не объект fstream. Используемые объекты будут связаны с одиним и тем же файлом, поэтому один поток должен быть закрыт до того, как откроется второй. Для этого будем использовать метод close().
В оперативной памяти данные будут размещены в виде динамической структуры данных. Так как информация хранится в классах, то элементом этой структуры является экземпляр класса. Использование для этих целей последовательного контейрнера – вектор обусловлено следующим:
пользователю необходимо предоставлять информацию о любом выбранном им рейсе, вне зависимости от места ее расположения (в конце или в начале структуры);
необходима быстрая вставка данных в конец структуры;
обращение к элементам должно осуществляться по индексу.
При добавлении, удалении и редактировании информации необходимо предусмотреть отмену последовательности действий. Пользователь должен иметь возможность отменить действия, которые он совершил при работе с программой. Чтобы это реализовать, необходимо сохранять информацию о проделанных пользователем действий. Т.е. о том, что пользователь изменил, добавил, удалил. После закрытия программы данную информацию необходимо удалить, поэтому сохранять ее в файле нет необходимости. Отмена последовательности действий должна производиться в обратном порядке. Первое совершенное действие должно отмениться последним, а последнее первым.
Для реализации это операции целесообразно использовать стек. В стеке должен храниться код операции (удаление, добавление, редактирование) и сама информация. При совершении операции данные заносится в вершину стека, при ее отмене, информация извлекается из вершины.
При сохранении информации о забронированных билетах, необходимо сохранять не весь экземпляр класса, а только его часть. При этом сохранять необходимо атрибуты класса, имеющие тип char и атрибут типа int, принимающего значения от 1 до 3. Поэтому для этой цели будем использовать форматированный файловый ввод/вывод, а не двоичный. Выбор данного метода организации файлового ввода/вывода обусловлено простым типом и небольшим объемом хранимых данных.
3. Описание программы для программиста
Для решения поставленной задачи были разработаны следующие классы:
class Raspis, класс расписания, содержит множество рейсов и позволяет производить различные операции, такие как вывод расписания на экран, добавление нового рейса, изменение выбранного, удаление рейса и др.;
class Reis, содержит информацию об отдельном авиарейсе;
class SpisOper, класс действий, содержит множество действий, выполненных пользователем.
Диаграмма классов представлена на рисунке 1.
Рассмотрим эти классы их атрибуты и методы.
class reis
{
napr n; // содержит город отправления и прибытия, расстояние между городами
char days[N2]; // дни курсирования 1-Пн, 2-Вт, … ,7-Вс
int m1; // количество мест 1 класса
int m2; // количество мест 2 класса
int m3; // количество мест 3 класса
public:
void Zap(); // Заполнение атрибутов класса
void ViewDays(); //Выводит на экран дни курсирования, //используется методом View() этого же класса
void View(int ); //выводит информацию об авиарейсе на экран, //входной параметр принимает значение:
//0 – вывод в ввиде таблицы
// 1 – подробный вывод
char *GetCityIn(); //возвращает город отправления
char *GetCityOut(); //возвращает город прибытия
char *GetDays(); //возвращает дни курсирования
};
Рассмотрим структуру napr:
struct napr
{
char cityin[N1]; //город отправления
char cityout[N1]; //город прибытия
int rast; //расстояние
};
Расстояние между городами необходимо для расчета стоимости проезда.
Класс reis и napr связаны композицией. Композиция – агрегация, при которой часть принадлежит только одному целому.
class Raspis
{
vector<reis> r; //содержит множество рейсов
public:
reis *inf(int); //выдает информацию об рейсе
void Pokaz();//Выводит
int Load();//загружает расписание из файла
int Save();//сохраняет расписание в файле
void Add(reis &,int);//добавляет новый элемент в расписание
void Delete(int);//удаляет элемент из расписания
void Edit();//позволяет редактировать элемент расписания
int Size();//выдает количество рейсов
};
Класс reis и raspis связаны агрегацией. Агрегация – ассоциация, представляющая «часть-целое».
Рисунок 1 – Диаграмма классов
В классе SpisOper хранится список произведенных пользователем действий. Он содержит стек в котором хранится необходимая информация. Методы этого класса позволяют после выполнения пользователем действия заносить их в стек, а при необходимости извлекать их.
В структуре Oper хранится ключ операции, позиция и информация об авиа рейсе. Под ключом операции подразумевается, то какая операция была произведена пользователем. Ключ может принимать значение 1 - при операции добавления, 2 – операции удаления, 3 – операции редактирования.
class SpisOper
{
stack<Oper> o;//стек содержащий действия произведенные пользователем
public:
void Add(Oper ); //добавления действия в стек
Oper Delete(); //извлечения из стека
int Pokaz();//вывод на экран последней произведенной операции
}
Для хранения информации об авиарейсе использется бинарный файл. В данном файле содержатся экзмпляры класса reis.
При чтении данных из файла используется поток ifstream. Информация из файла считывается, затем поток закрывается методом close().
При записи информации в файла используется поток оfstream. Информация в файл записывается, после чего поток так же закрывается методом close().
Для сохранения информации о забронированных билетах, используется форматированный ввод-вывод. Содержание файла представлео на рисунке 2.
Рисунок 2 – Содержание файла bilet.dat