Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.76 KB | None | 0 0
  1. #include <fstream>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <iomanip>
  6. #include <iostream>
  7. using namespace std;
  8.  
  9. char* filename="dbase";
  10. enum Action {INSERT, DEL, INFO};
  11. enum Dir {LEFT, RIGHT};
  12. const int l_time=20, l_type=40, l_number=12;
  13. struct Fine {           // Штраф (элемент списка)
  14.     char time[l_time];  // Время нарушения
  15.     char type[l_type];  // Вид нарушения
  16.     float price;        // Размер штрафа
  17.     Fine* next;         // Указатель на следующий элемент
  18.     };
  19. struct Node {               // Узел дерева
  20.     char number[l_number];  // Номер автомашины
  21.     Fine* beg;              // Указатель на начало списка нарушений
  22.     Node* left;             // Указатель на левое поддерево
  23.     Node* right;            // указатель на правое поддерево
  24.     };
  25. struct Data {               // Исходные данные
  26.     char number[l_time];    // Номер автомашины
  27.     char time[l_time];      // Время нарушения
  28.     char type[l_type];      // Вид нарушения
  29.     float price;            // Размер штрафа
  30.     };
  31. Node* descent(Node* p);
  32. Node* first(Data data);
  33. Data input(Action action);
  34. int menu();
  35. void print_node(const Node& node);
  36. void print_dbase(Node* p);
  37. Node* read_dbase(char* filename);
  38. int read_fine(ifstream f, Data& data);
  39. int remove_fine(Node* p, const Data& data);
  40. void remove_fines(Node* p);
  41. Node* remove_node(Node* root, Node* p, Node* parent, Dir dir);
  42. Node* remove_tree(Node* p);
  43. Node* seach_insert(Node* root, const Data& data, Action action, Dir& dir, Node*& parent);
  44. void write_dbase(ofstream f, const Node* root);
  45. void write_node(ofstream f, const Node& node);
  46. // -------------  Главная функция
  47. int main() {
  48.     Node* p, *parent;
  49.     Node* root=read_dbase(filename);
  50.     ofstream fout;
  51.     Dir dir;
  52.     Data data;
  53.     while (true) {
  54.         switch (menu()) {
  55.         case 1:     // Ввод сведений о нарушении
  56.             if (!root) root=first(input(INSERT));
  57.  p=(Node*)seach_insert(root, input(INSERT), INSERT, dir, parent);
  58.             break;
  59.          case 2:        // Ввод сведений об оплате штрафа
  60.             if (!root) {cout<<"База пуста"<<endl; break;}
  61.             Data data=input(DEL);
  62.             if(!(p=(Node*)search_insert(root, data, DEL, dir, parent)))
  63.                 cout<<"сведения об автомобиле отсутствуют"<<endl;
  64.             else
  65.                 if(remove_fine(p, data)==2)     // Удалены все нарушения
  66.                     root=remove_node(root, p, parent, dir);
  67.                 break;
  68.         case 3:     // Справка
  69.             if (!root) {cout<<"База пуста"<<endl; break;}
  70.             if (!(p=(Node*)search_insert(root, input(INFO), INFO, dir, parent)))
  71.                 cout<<"Сведения отсутствуют"<<endl;
  72.             else print_node(*p);
  73.             break;
  74.         case 4:     // Выход
  75.             fout.open(filename);
  76.             if (!fout.is_open()) {
  77.             cout<<"Ошибка открытия файла"<<filename<<endl; return 1;
  78.             }
  79.         write_dbase(fout, root);
  80.         return 0;
  81.         case 5:     // Отладка
  82.             print_dbase(root);
  83.             break;
  84.         default:
  85.             cout<<"Надо вводить число от 1 до 4"<<endl;
  86.             break;
  87.         }
  88.     }
  89.     return 0;
  90. }
  91. // -------------  Спуск по дереву
  92. Node* descent(Node* p) {
  93.     Node* prev, *y=p->right;
  94.     if (!y->left) y->left=p->left;          // 1
  95.     else {
  96.         do {prev=y; y=y->left;}     // 2
  97.         while(y->left);
  98.         y->left=p->left;            // 3
  99.         prev->left=y->right;            // 4
  100.         y->right=p->right;          // 5
  101.     }
  102.     return y;
  103. }
  104. // ------------- Формирвание корневого элемента дерева
  105. Node* first(Data data) {
  106.     // Создание записи о нарушении:
  107.     Fine* beg=new Fine;
  108.     strncpy(beg->time, data.time, l_time);
  109.     strncpy(beg->type, data.type, l_type);
  110.     beg->price=data.price;
  111.     beg->next=0;
  112.     // Создание первого узла дерева:
  113.     Node* root=new Node;
  114.     strncpy(root->number, data.number, l_number);
  115.     root->beg=beg;
  116.     root->left=root->right=0;
  117.     return root;
  118.     }
  119. // ------------- Ввод нарушения
  120. Data input(Action action) {
  121.     Data data;
  122.     char buf[10], temp1[3], temp2[3];
  123.     int day, month, hour, min;
  124.     cout<<"Введите номер а/м"<<endl;
  125.     cin.getline(data.number, l_number);
  126.     if (action==INFO) return data;
  127.     do {
  128.         cout<<"Введите дату нарушения в формате ДД.ММ.ГГ:"<<endl;
  129.         cin>>buf;
  130.         strncpy(temp1, buf, 2);
  131.         strncpy(temp2, &buf[3],2);
  132.         day=atoi(temp1); month=atoi(temp2);
  133.     }
  134.     while (!(day>0 && day<32 && month>0 && month<13));
  135.     strcpy(data.time, buf); strcat(data.time, " ");
  136.     do {
  137.         cout<<"Введите время нарушения в формате ЧЧ:ММ"<<endl;
  138.         cin>>buf;
  139.         strncpy(temp1, buf, 2); strncpy(temp2, &buf[3], 2);
  140.         hour=atoi(temp1); min=atoi(temp2);
  141.     }
  142.     while (!(hour>=0 && hour<24 && min>=0 && min<60));
  143.     strcat(data.time, buf);
  144.     cin.get();
  145.     if (action==DEL) return data;
  146.     cout<<"Введите тип нарушения type"<<endl;
  147.     cin.getline(data.type, l_type);
  148.     do {
  149.         cout<<"Введите размер штрафа:"<<endl;
  150.         cin>>buf;
  151.     }
  152.     while (!(data.price=(float)atof(buf)));
  153.     cin.get();
  154.     return data;
  155.     }
  156. // ------------- вывод меню
  157. int menu() {
  158.     char buf[10];
  159.     int option;
  160.     do {       
  161.         cout<<"=============================="<<endl;
  162.         cout<<"1 - ввод сведений о нарушении"<<endl;     
  163.         cout<<"2 - ввод сведений об оплате штрафа"<<endl;
  164.         cout<<"3 - Справка"<<endl;
  165.         cout<<"4 - выход сведений о нарушении"<<endl;
  166.         cout<<"=============================="<<endl;
  167.         cin>>buf; option=atoi(buf);
  168.     }
  169.     while (!option);
  170.     cin.get();
  171.     return option;
  172. }
  173. // ------------- Вывод на экран сведений об а/м
  174. void print_node(const Node& node) {
  175.     cout<<"Номер а/м"<<node.number<<endl;
  176.     Fine* pf=node.beg;
  177.     float summa=0;
  178.     while (pf) {
  179.         cout<<"Вид нарушения"<<pf->type<<endl;
  180.         cout<<"Дата и время"<<pf->time;
  181.         cout<<"Размер штрафа"<<pf->price<<endl;
  182.         summa+=pf->price;
  183.         pf=pf->next;
  184.         }
  185.     cout<<"Общая сумма штрафов"<<summa<<endl;
  186.     }
  187. // ------------- Вывод на экран всего дерева
  188. void print_dbase(Node *p) {
  189.     if (p) {
  190.     print_node(*p);
  191.     print_dbase (p->left);
  192.     print_dbase (p->right);
  193.         }
  194.     }
  195. // ------------- Чтение базы из файла
  196. Node* read_dbase (char* filename) {
  197.     Node *parent;
  198.     Dir dir;
  199.     Data data;
  200.     ifstream f(filename, ios::in);
  201.     if (!f) { cout<<"Нет файла"<<filename<<endl; return 0;}
  202.     f.getline(data.number, l_number);       // Номер а/м
  203.     if(f.eof()) {cout<<"Пустой файл (0 байт)"<<endl; return 0;}
  204.     read_fine(f, data);         // Первое нарушение
  205.     Node* root=first(data);     // формирование корня дерева
  206.     while (!read_fine(f, data)) // Последующие нарушения
  207.         search_insert(root, data, INSERT, dir, parent);
  208. // ------------- Формирование дерева
  209.     while (f.getline(data.number, l_number)) { // Номер а/м
  210.         read_fine(f, data);                 // Первое нарушение
  211.         search_insert(root, data, INSERT, dir, parent);
  212.         while (!read_fine(f, data))         // Последующие нарушения
  213.             search_insert(root, data, INSERT, dir, parent);
  214.     }
  215.     return root;
  216. }
  217. // ------------- Чтение из файла информации о нарушении
  218. int read_fine(ifstream f, Data& data) {
  219.     f.getline(data.time, l_time);
  220.     if(data.time[0]=='=') return 1;         // Конец списка нарушений
  221.     f.getline(data.type, l_type);
  222.     f>>data.price;
  223.     f.get();
  224.     return 0;                       // нарушение считано успешно
  225. }
  226. // ------------- Удаление нарушения из списка
  227. int remove_fine(Node* p, const Data& data) {
  228.     Fine* prev, *pf=p->beg;
  229.     bool found=false;
  230.     while (pf && !found) {                  // Цикл по списку нарушений
  231.         if(!strcmp(pf->time, data.time))
  232.             found=true;                 // Нарушение найдено
  233.         else {
  234.             prev=pf;
  235.             pf=pf->next;                    // переход к следующему элементу списка
  236.         }
  237.     }
  238.     if (!found) {
  239.         cout<<"Сведения о нарушении отсутствуют"<<endl;
  240.         return 1;
  241.     }
  242.     if (pf==p->beg)                         // Удаление из начала списка
  243.         p->beg=pf->next;
  244.     else                                    // Удаление из середины или конца списка
  245.         prev->next=pf->next;
  246.     delete pf;                              // Освобождение памяти из-под элемента
  247.     if (!p->beg) return 2;                  // Список пуст
  248.     return 0;
  249.     }
  250. // ------------- Удаление узла дерева
  251. Node* remove_node(Node* root, Node* p, Node* parent, Dir dir) {
  252.     Node *y;        // Узел, заменяющий удаляемый
  253.     if (!p->left) y=p->right;           // 11
  254.     else if (!p->right) y=p->left;          // 12
  255.     else y=descent(p);              // 13
  256.     if (p==root) root=y;                // 14
  257.     else {                      // 15
  258.         if (dir==LEFT) parent->left=y;
  259.         else parent->right=y;
  260.         }
  261.     delete p;                   // 16
  262.     return root;
  263.     }
  264. // ------------- Поиск с включением
  265. Node* seach_insert(Node* root, const Data& data, Action action, Dir& dir, Node*& parent) {
  266.     Node* p=root;           // Указатель на текущий элемент
  267.     bool found=false;       // Признак успешного поиска
  268.     int cmp;                // Результат сравнения ключей
  269.     parent=0;
  270.     while (p && !found) {   // Цикл поиска по дереву
  271.         cmp=strcmp(data.number, p->number);     // Сравнение ключей
  272.         if (!cmp) found=true;                   // Нашли
  273.         else {
  274.             parent=p;
  275.             if (cmp<0) { p=p->left; dir=LEFT;}  // Спуск влево
  276.             else {p=p->right; dir=RIGHT; }      // Спуск вправо
  277.         }
  278.     }
  279.     if (action != INSERT) return p;
  280.     // Создание записи о нарушении:
  281.     Fine* pf=new Fine;
  282.     strncpy(pf->time, data.time, l_time);
  283.     strncpy(pf->type, data.type, l_type);
  284.     pf->price=data.price;
  285.     pf->next=0;
  286.     if (!found) {
  287.         // Создание нового узла
  288.         p=new Node;
  289.         strncpy(p->number, data.number, l_number);
  290.         p->beg=pf;
  291.         p->left=p->right=0;
  292.         if (dir==LEFT)          // Присоединение к левому поддереву предка
  293.             parent->left=p;
  294.         else
  295.             parent->right=p;
  296.     }
  297.     return p;
  298. }
  299. // ------------- вывод базы в файл
  300. void write_dbase(ofstream f, const Node *p) {
  301.     if (p) {
  302.         write_node(f, *p);
  303.         write_dbase(f, p->left);
  304.         write_dbase(f, p->right);
  305.         }
  306.     }
  307. // ------------- Вывод в файл сведений об а/м
  308. void write_node(ofstream f, const Node& node) {
  309.     f<<node.number<<endl;
  310.     Fine* pf=node.beg;
  311.     while(pf) {
  312.         f<<pf->time<<endl<<pf->type<<endl<<pf->price<<endl;
  313.         pf=pf->next;
  314.     }
  315.     f<<"="<<endl;           // Признак окончания сведений об а/м
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement