Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.65 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <map>
  5. #include <set>
  6. #include <exception>
  7. #include <fstream>
  8. #include <iomanip>
  9. #include <sstream>
  10. #include <cctype>   // для функции isdigit
  11. //#include <ctype>
  12.  
  13.  
  14. using namespace std;
  15.  
  16. // дата
  17. class Date {
  18. public:
  19.     Date() {
  20.         Year = -1; Month = -1; Day = -1;
  21.     };
  22.     Date(int y, int m, int d)
  23.     {
  24.         if ((m > 12 || m < 1) && (d > 31 || d < 1))
  25.         {
  26.             string string_err = "Month value is invalid: " + to_string(m);
  27.             throw invalid_argument(string_err);
  28.         }
  29.         else if (m > 12 || m < 1)
  30.         { //Month value is invalid: MONTH
  31.             string string_err = "Month value is invalid: " + to_string(m);
  32.             throw invalid_argument(string_err);
  33.         }
  34.         else if (d < 1 || d>31)
  35.         {
  36.             string string_err = "Day value is invalid: " + to_string(d);
  37.             throw invalid_argument(string_err);
  38.         }
  39.         else
  40.         {
  41.             Year = y;
  42.             Month = m;
  43.             Day = d;
  44.         }
  45.     }
  46.  
  47. public:
  48.     int GetYear() const
  49.     {
  50.         return Year;
  51.     };
  52.     int GetMonth() const
  53.     {
  54.         return Month;
  55.     };
  56.     int GetDay() const
  57.     {
  58.         return Day;
  59.     };
  60. private:
  61.     int Year;
  62.     int Month;
  63.     int Day;
  64. };
  65.  
  66. bool operator<(const Date& lhs, const Date& rhs)
  67. {
  68.     if (lhs.GetYear() == rhs.GetYear())
  69.     {
  70.         if (lhs.GetMonth() == rhs.GetMonth())
  71.         {
  72.             return lhs.GetDay() < rhs.GetDay();
  73.         }
  74.         else return lhs.GetMonth() < rhs.GetMonth();
  75.     }
  76.     else return lhs.GetYear() < rhs.GetYear();
  77. };
  78.  
  79. bool operator==(const Date& lhs, const Date& rhs)
  80. {
  81.     if (lhs.GetYear() == rhs.GetYear())
  82.     {
  83.         if (lhs.GetMonth() == rhs.GetMonth())
  84.         {
  85.             return lhs.GetDay() == rhs.GetDay();
  86.         }
  87.         else return false;
  88.     }
  89.     else return false;
  90. };
  91. // вывод даты в нужном формате
  92. ostream& operator << (ostream& stream, const Date& date)
  93. {
  94.     stream << setw(4)<< setfill('0')<< date.GetYear() << "-" << setw(2) << setfill('0') << date.GetMonth()<<"-" << setw(2) << setfill('0') <<date.GetDay();
  95.     return stream;
  96. }
  97.  
  98.  
  99. /// преобразователь строки в вектор с датой, всё посимвольно
  100. vector<int> ParseDate(const string& date_str)
  101. {
  102.     vector<int> date_vec;
  103.     string part, year, month, day;
  104.     int def_count = 0; // счетчик тире
  105.  
  106.     for (int i = 0; i < date_str.size(); ++i)
  107.     {
  108.         if (date_str[i] != '-')
  109.         {
  110.             // если не тире, проверяем, цифра ли это
  111.             if ((date_str[i] >= '0' && date_str[i] <= '9') && def_count == 0) {
  112.                 year += date_str[i];
  113.             }
  114.             else if ((date_str[i] >= '0' && date_str[i] <= '9') && def_count == 1) {
  115.                 month += date_str[i];
  116.             }
  117.             else if ((date_str[i] >= '0' && date_str[i] <= '9') && def_count == 2) {
  118.                 day += date_str[i];
  119.             }
  120.             else {
  121.                 throw runtime_error("Wrong date format: " + date_str);
  122.             }
  123.         }
  124.         else
  125.         {
  126.             def_count++;
  127.         }
  128.         if (def_count > 2) throw runtime_error("Wrong date format: " + date_str);
  129.     }
  130.  
  131.     if(year !="" && month != "" && day != "")
  132.     {
  133.         if (year.size() <= 4 && month.size() <= 2 && day.size() <= 2)
  134.         {
  135.             date_vec.push_back(stoi(year));
  136.             date_vec.push_back(stoi(month));
  137.             date_vec.push_back(stoi(day));
  138.         }
  139.         else
  140.             throw runtime_error("Wrong date format: " + date_str);
  141.  
  142.     }
  143.     else
  144.         throw runtime_error("Wrong date format: " + date_str);
  145.    
  146.     return date_vec;
  147. }
  148.  
  149. // попытка считать дату из потока
  150. vector<int> ParseDateFlow(const string& date_str)
  151. {
  152.     vector<int> date_vec;
  153.     stringstream sstr(date_str);
  154.     string year, month, day;
  155.     string year_itog, month_itog, day_itog;
  156.     int flag_y = 1;
  157.     int flag_m = 1;
  158.     int flag_d = 1;
  159.  
  160.     int i_year, i_month, i_day;
  161.     int def_count = 0; // счетчик тире
  162.  
  163.     // если в строке не только тире и цифры, надо вылететь
  164.     for (int i = 0; i < date_str.size(); ++i)
  165.     {
  166.         if((date_str[i]< '0' || date_str[i]> '9') && date_str[i] != '-') throw runtime_error("Wrong date format: " + date_str);
  167.     }
  168.  
  169.     sstr >> i_year;
  170.     if(!(i_year >= 0 && i_year <= 9999)) throw runtime_error("Wrong date format: " + date_str);
  171.     sstr.ignore(1);
  172.     sstr >> i_month;
  173.     sstr.ignore(1);
  174.     sstr >> i_day;
  175.  
  176.     if(!sstr.eof()) throw runtime_error("Wrong date format: " + date_str);
  177.  
  178.     date_vec.push_back(i_year);
  179.     date_vec.push_back(i_month);
  180.     date_vec.push_back(i_day);
  181.  
  182.     return date_vec;
  183. }
  184.  
  185. // структура для ввода команды
  186. struct command_struct
  187. {
  188.     string command = "";
  189.     Date date;
  190.     string event = "";
  191. };
  192.  
  193. // заполняем структуру
  194. command_struct struct_from_command(const string& com)
  195. {
  196.     command_struct cs;
  197.     stringstream in;
  198.    
  199.     in.str(com);
  200.     in >> cs.command;
  201.     in.ignore(1);
  202.  
  203.     string date;
  204.     in >> date;
  205.     if (date != "")
  206.     {
  207.         vector<int> dv = ParseDateFlow(date);
  208.         cs.date = Date(dv.at(0), dv.at(1), dv.at(2));
  209.     }
  210.  
  211.     in.ignore(1);
  212.     in >> cs.event;
  213.     return cs;
  214. }
  215.  
  216. // класс базы данных
  217. class Database {
  218. public:
  219.   void AddEvent(const Date& date, const string& event);
  220.   bool DeleteEvent(const Date& date, const string& event);
  221.   int  DeleteDate(const Date& date);
  222.  
  223.   set<string> Find(const Date& date) const;
  224.  
  225.   void Print() const;
  226. private:
  227.     map<Date, set<string> > database;
  228. };
  229.  
  230. void Database::AddEvent(const Date& date, const string& event)
  231. {
  232.     // ещё раз проверим дату
  233.     if (date.GetYear() >= 0 && date.GetMonth() > 0 && date.GetDay() > 0)
  234.     {
  235.         if (event != "")  // и если событие ненулевое
  236.         {
  237.             database[date].insert(event);
  238.         }
  239.     }
  240.     //else throw runtime_error("Wrong date format: ");
  241. }
  242.  
  243. //1. Удалить можно только ранее добавленные события.Если событие найдено и удалено, то программа должна вывести
  244. //строку «Deleted successfully»(без кавычек).Если событие в указанную дату не найдено, то программа должна
  245. //вывести строку «Event not found»(без кавычек).
  246.  
  247. bool Database::DeleteEvent(const Date& date, const string& event)
  248. {
  249.     set<string> found_events;
  250.     if (database.size() > 0)
  251.     {
  252.         if(database.find(date)!= database.end())
  253.         {
  254.             found_events = database.at(date);
  255.             if (found_events.size() > 0) {
  256.                 for (const auto& item : found_events)
  257.                 {
  258.                     if (item == event)
  259.                     {
  260.                         database[date].erase(event);
  261.                         // если мы удалили последнее событие, удалим всю дату
  262.                         if (database[date].size() == 0)
  263.                         {
  264.                             database.erase(date);
  265.                         }
  266.                         return true;
  267.                     }
  268.                 }
  269.             }
  270.             else return false;
  271.         }      
  272.         else return false;
  273.     }
  274.     else return false;
  275. }
  276. // 2. Команда удаляет все ранее добавленные события за указанную дату. Программа всегда должна выводить строку
  277. // вида «Deleted N events», где N — это количество всех найденных и удалённых событий. N может быть равно нулю,
  278. // если в указанную дату не было ни одного события.
  279. int  Database::DeleteDate(const Date& date)
  280. {
  281.     if (database.size() > 0)
  282.     {
  283.         if (database.find(date)!=database.end())
  284.         {
  285.             int k = database.at(date).size();
  286.             database.erase(date);
  287.             return k;
  288.         }
  289.     }
  290.     return 0;
  291. };
  292.  
  293. set<string> Database::Find(const Date& date) const
  294. {
  295.     set<string> date_events = {""};
  296.     date_events.clear();
  297.     if(database.find(date)!=database.end())
  298.     {
  299.         date_events = database.at(date);
  300.     }
  301.     return date_events;
  302.    
  303. };
  304.  
  305. //С помощью этой команды можно показать полное содержимое нашей БД.Программа должна вывести на печать
  306. void Database::Print() const
  307. {
  308.     for (const auto& item1 : database)
  309.     {
  310.         for (const auto& item2 : item1.second)
  311.         {
  312.             cout << item1.first<< " "<< item2 << endl;
  313.         }
  314.     }
  315. };
  316.  
  317.  
  318. ////////////////////////////////////////////////////////////////////////////
  319. int main() {
  320.   Database db;
  321.    
  322.   //-добавление события : Add Дата Событие
  323.  // - удаление события : Del Дата Событие
  324.  // - удаление всех событий за конкретную дату : Del Дата
  325.  // - поиск событий за конкретную дату : Find Дата
  326.  // - печать всех событий за все даты : Print
  327.  
  328.   string command;
  329.   string event_str;
  330.   Date event_date;
  331.  
  332.   while (getline(cin, command)) {
  333.     // Считайте команды с потока ввода и обработайте каждую
  334.       // написать функцию, которая разбирает команду
  335.  
  336.       if (command == "") continue;
  337.       else
  338.       {
  339.           stringstream cs0(command);
  340.           string com, ev;
  341.           string cs0date;
  342.           cs0 >> com;
  343.           cs0.ignore(1);
  344.           cs0 >> cs0date;
  345.           cs0.ignore(1);
  346.           cs0 >> ev;
  347.           // проверим, правильные ли все команды
  348.           try {
  349.  
  350.               if (com == "Add" || com == "Find" || com == "Del" || com == "Print")
  351.               {
  352.                   // для 3го теста
  353.                   if (com == "Add" && ev == "") throw runtime_error("Wrong date format: " + cs0date);
  354.                   else
  355.                   {
  356.                       try
  357.                       {
  358.                           command_struct cs1;
  359.                           cs1 = struct_from_command(command);
  360.                           if (cs1.command == "Add") // добавить событие в базу
  361.                           {
  362.                               if (cs0date == "") { throw runtime_error("Wrong date format: " + cs0date); }
  363.                               else {
  364.                                       if (ev != "")
  365.                                       {
  366.                                           db.AddEvent(cs1.date, cs1.event);
  367.                                       }
  368.                               }
  369.                               //}
  370.                           }
  371.                           else if (cs1.command == "Del")
  372.                           {
  373.                               if (cs0date == "") { throw runtime_error("Wrong date format: " + cs0date); }
  374.                               else
  375.                               {
  376.                                   if (cs1.event == "")
  377.                                   {
  378.                                       int N = db.DeleteDate(cs1.date);
  379.                                       cout << "Deleted " << N << " events" << endl;
  380.                                   }
  381.                                   else
  382.                                   {
  383.                                       if (db.DeleteEvent(cs1.date, cs1.event) == true)
  384.                                       {
  385.                                           cout << "Deleted successfully" << endl;
  386.                                       }
  387.                                       else cout << "Event not found" << endl;
  388.                                   }
  389.  
  390.                               }
  391.  
  392.                           }
  393.                           else if (cs1.command == "Find")
  394.                           {
  395.  
  396.                               //Ищем и печатаем ранее добавленные события в указанную дату.Программа должна вывести на печать только сами события,
  397.                               //по одному на строке.События должны быть отсортированы по возрастанию в порядке сравнения строк между собой(тип string).
  398.                               if (cs0date == "") { throw runtime_error("Wrong date format: " + cs0date); }
  399.                               else
  400.                               {
  401.                                   set<string> found_events = db.Find(cs1.date);
  402.                                   if (found_events.size() > 0)
  403.                                   {
  404.                                       for (auto item : found_events)
  405.                                       {
  406.                                           cout << item << endl;
  407.                                       }
  408.                                   }
  409.                               }
  410.                           }
  411.                           else if (cs1.command == "Print")
  412.                           {
  413.                               db.Print();
  414.                           }
  415.                       }
  416.                       catch (exception& ex) {
  417.                           throw ex;
  418.                       }
  419.                   }
  420.                  
  421.               }
  422.               else // неизвестная команда
  423.               {
  424.                   throw runtime_error( "Unknown command: " + com );
  425.               }
  426.           }
  427.           catch (invalid_argument& ia)
  428.           {
  429.               cout << ia.what() << endl;
  430.               return 0;
  431.           }
  432.           catch (runtime_error& re)
  433.           {
  434.               cout << re.what() << endl;
  435.               return 0;
  436.           }
  437.           catch (exception& ex)
  438.           {
  439.               cout << ex.what() << endl;
  440.               return 0;
  441.           }
  442.       } // else if command != ""
  443.      
  444.   } // while
  445.  
  446.   return 0;
  447. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement