Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.45 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <optional>
  4. #include <cassert>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <cctype>
  8. #include <unordered_map>
  9.  
  10. struct Number {
  11.     std::string number_ = "";
  12.  
  13.     Number() = default;
  14.  
  15.     explicit Number(const std::string& number) : number_(number) {}
  16.  
  17.     std::string GetNormalizedString() const {
  18.         return number_[0] == '+' ? number_.substr(1, number_.length() - 1) : number_;
  19.     }
  20. };
  21.  
  22. struct Address {
  23.     std::optional<std::string> address_;
  24.  
  25.     Address() = default;
  26.  
  27.     explicit Address(const std::string& address) {
  28.         address_.emplace(address);
  29.     }
  30.  
  31.     std::string GetNormalizedString() const {
  32.         return address_.has_value() ? address_.value() : "";
  33.     }
  34. };
  35.  
  36. struct Name {
  37.     std::string name_ = "";
  38.  
  39.     Name() = default;
  40.  
  41.     explicit Name(const std::string& name) : name_(name){}
  42.  
  43.     std::string GetNormalizedString() const {
  44.         std::vector<std::string> vector;
  45.         int j = -1;
  46.         for (size_t i = 0; i < name_.length(); ++i) {
  47.             if (!isalpha(name_[i])) {
  48.                 if (i != j + 1) {
  49.                     vector.push_back(name_.substr(j + 1, i - j - 1));
  50.                 }
  51.                 j = i;
  52.             }
  53.         }
  54.         if (j + 1 != name_.length()) {
  55.             vector.push_back(name_.substr(j + 1, name_.length() - j));
  56.         }
  57.         for (auto &elem : vector) {
  58.             for (auto &ch : elem) {
  59.                 ch = tolower(ch);
  60.             }
  61.         }
  62.         std::sort(vector.begin(), vector.end());
  63.         std::string res;
  64.         for (const auto &elem : vector) {
  65.             res += elem;
  66.             res += " ";
  67.         }
  68.         return res.empty() ? res : res.substr(0, res.length() - 1);
  69.     }
  70. };
  71.  
  72. class Contact {
  73. private:
  74.     int id_;
  75.     Name name_;
  76.     Number number_;
  77.     Address address_;
  78.  
  79. public:
  80.     Contact() : id_(-1), name_(Name()), number_(Number()), address_(Address()) {}
  81.  
  82.     Contact(int id, const std::string& name, const std::string& number, const std::string& address)
  83.             : id_(id), name_(name), number_(number), address_(address){}
  84.  
  85.     Contact(const std::string& name, const std::string& number, const std::string& address)
  86.             : id_(-1), name_(name), number_(number), address_(address){}
  87.  
  88.     int GetId() const {
  89.         return id_;
  90.     }
  91.  
  92.     std::string GetName() const {
  93.         return name_.name_;
  94.     }
  95.  
  96.     std::string GetNumber() const {
  97.         return number_.number_;
  98.     }
  99.  
  100.     std::string GetAddress() const {
  101.         return address_.address_.has_value() ? address_.address_.value() : "";
  102.     }
  103.  
  104.     void SetId(int id) {
  105.         id_ = id;
  106.     }
  107.  
  108.     void SetName(const std::string name) {
  109.         name_.name_ = name;
  110.     }
  111.  
  112.     void SetNumber(const std::string number) {
  113.         number_.number_ = number;
  114.     }
  115.  
  116.     void SetAddress(const std::string address) {
  117.         address_.address_.emplace(address);
  118.     }
  119.  
  120.     std::string GetNormalizedName() const {
  121.         return name_.GetNormalizedString();
  122.     }
  123.  
  124.     std::string GetNormalizedNumber() const {
  125.         return number_.GetNormalizedString();
  126.     }
  127.  
  128.     std::string GetNormalizedAddress() const {
  129.         return address_.GetNormalizedString();
  130.     }
  131.  
  132.  
  133. };
  134.  
  135. class PhoneBook {
  136. private:
  137.     std::unordered_map<int, Contact*> map_id_;
  138.     std::unordered_map<std::string, Contact*> map_name_;
  139.     std::unordered_map<std::string, Contact*> map_number_;
  140.     int max_id_ = 0;
  141.  
  142.     Contact* GetContactPtrById(int id) const {
  143.         if (map_id_.count(id) == 0) {
  144.             return nullptr;
  145.         }
  146.         return map_id_.at(id);
  147.     }
  148.  
  149.     Contact* GetContactPtrByName(const std::string& name) const {
  150.         auto n = Name(name).GetNormalizedString();
  151.         if (map_name_.count(n) == 0) {
  152.             return nullptr;
  153.         }
  154.         return map_name_.at(n);
  155.     }
  156.  
  157.     Contact* GetContactPtrByNumber(const std::string& number) const {
  158.         auto n = Number(number).GetNormalizedString();
  159.         if (map_number_.count(n) == 0) {
  160.             return nullptr;
  161.         }
  162.         return map_number_.at(n);
  163.     }
  164.  
  165. public:
  166.     PhoneBook() : max_id_(0) {}
  167.  
  168.     int AddContact(const std::string& name, const std::string& number, const std::string& address) {
  169.         if (map_name_.count(Name(name).GetNormalizedString()) > 0 ||
  170.             map_number_.count(Number(number).GetNormalizedString()) > 0) {
  171.             return -1;
  172.         }
  173.         auto* contact = new Contact(max_id_++, name, number, address);
  174.         map_id_[max_id_ - 1] = contact;
  175.         map_name_[contact->GetNormalizedName()] = contact;
  176.         map_number_[contact->GetNormalizedNumber()] = contact;
  177.         return max_id_ - 1;
  178.     }
  179.  
  180.     ~PhoneBook() {
  181.         for (const auto& elem : map_id_) {
  182.             delete elem.second;
  183.         }
  184.     }
  185.  
  186.     PhoneBook(const PhoneBook& rhs) : max_id_(rhs.max_id_) {
  187.         for (const auto& elem : map_id_) {
  188.             delete map_id_[elem.first];
  189.         }
  190.         map_id_.clear();
  191.         map_name_.clear();
  192.         map_number_.clear();
  193.         for (const auto& elem : rhs.map_id_) {
  194.             auto* contact = new Contact(elem.first, elem.second->GetName(), elem.second->GetNumber(),
  195.                                         elem.second->GetAddress());
  196.             map_id_[elem.first] = contact;
  197.             map_name_[contact->GetNormalizedName()] = contact;
  198.             map_number_[contact->GetNormalizedNumber()] = contact;
  199.         }
  200.     }
  201.  
  202.     PhoneBook& operator=(const PhoneBook& rhs) {
  203.         if (this != &rhs) {
  204.             max_id_ = rhs.max_id_;
  205.             for (const auto& elem : map_id_) {
  206.                 delete map_id_[elem.first];
  207.             }
  208.             map_id_.clear();
  209.             map_name_.clear();
  210.             map_number_.clear();
  211.             for (const auto& elem : rhs.map_id_) {
  212.                 auto* contact = new Contact(elem.first, elem.second->GetName(), elem.second->GetNumber(),
  213.                                             elem.second->GetAddress());
  214.                 map_id_[elem.first] = contact;
  215.                 map_name_[contact->GetNormalizedName()] = contact;
  216.                 map_number_[contact->GetNormalizedNumber()] = contact;
  217.             }
  218.         }
  219.         return *this;
  220.     }
  221.  
  222.     PhoneBook(PhoneBook&& rhs) = default;
  223.  
  224.     PhoneBook& operator=(PhoneBook&& rhs) = default;
  225.  
  226.     std::vector<Contact> GetContactsByAddress(const std::string& address) const {
  227.         std::vector<Contact> vector;
  228.         for (const auto& elem : map_id_) {
  229.             if (elem.second->GetNormalizedAddress().find(address) != std::string::npos) {
  230.                 vector.push_back(*elem.second);
  231.             }
  232.         }
  233.         return vector;
  234.     }
  235.  
  236.     Contact GetContactById(int id, bool* flag) const {
  237.         auto contact_ptr = GetContactPtrById(id);
  238.         *flag = contact_ptr != nullptr;
  239.         return *flag ? *map_id_.at(id) : Contact();
  240.     }
  241.  
  242.     void SetNameById(const std::string& name, int id) {
  243.         auto contact_ptr = GetContactPtrById(id);
  244.         if (contact_ptr != nullptr) {
  245.             map_name_.erase(contact_ptr->GetNormalizedName());
  246.             contact_ptr->SetName(name);
  247.             map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
  248.         }
  249.     }
  250.  
  251.     void SetNumberById(const std::string& number, int id) {
  252.         auto contact_ptr = GetContactPtrById(id);
  253.         if (contact_ptr != nullptr) {
  254.             map_number_.erase(contact_ptr->GetNormalizedNumber());
  255.             contact_ptr->SetNumber(number);
  256.             map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
  257.         }
  258.     }
  259.  
  260.     void SetAddressById(const std::string& address, int id) {
  261.         auto contact_ptr = GetContactPtrById(id);
  262.         if (contact_ptr != nullptr) {
  263.             contact_ptr->SetAddress(address);
  264.         }
  265.     }
  266.  
  267.     Contact GetContactByName(const std::string& name, bool* flag) const {
  268.         auto contact_ptr = GetContactPtrByName(name);
  269.         *flag = contact_ptr != nullptr;
  270.         return *flag ? *map_name_.at(name) : Contact();
  271.     }
  272.  
  273.     void SetNameByName(const std::string& name, const std::string& n) {
  274.         auto contact_ptr = GetContactPtrByName(n);
  275.         if (contact_ptr != nullptr) {
  276.             map_name_.erase(contact_ptr->GetNormalizedName());
  277.             contact_ptr->SetName(name);
  278.             map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
  279.         }
  280.     }
  281.  
  282.     void SetNumberByName(const std::string& number, const std::string& n) {
  283.         auto contact_ptr = GetContactPtrByName(n);
  284.         if (contact_ptr != nullptr) {
  285.             map_number_.erase(contact_ptr->GetNormalizedNumber());
  286.             contact_ptr->SetNumber(number);
  287.             map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
  288.         }
  289.     }
  290.  
  291.     void SetAddressByName(const std::string& address, const std::string& n) {
  292.         auto contact_ptr = GetContactPtrByName(n);
  293.         if (contact_ptr != nullptr) {
  294.             contact_ptr->SetAddress(address);
  295.         }
  296.     }
  297.  
  298.     Contact GetContactByNumber(const std::string& number, bool* flag) const {
  299.         auto contact_ptr = GetContactPtrByNumber(number);
  300.         *flag = contact_ptr != nullptr;
  301.         return *flag ? *map_number_.at(number) : Contact();
  302.     }
  303.  
  304.     void SetNameByNumber(const std::string& name, const std::string& n) {
  305.         auto contact_ptr = GetContactPtrByNumber(n);
  306.         if (contact_ptr != nullptr) {
  307.             map_name_.erase(contact_ptr->GetNormalizedName());
  308.             contact_ptr->SetName(name);
  309.             map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
  310.         }
  311.     }
  312.  
  313.     void SetNumberByNumber(const std::string& number, const std::string& n) {
  314.         auto contact_ptr = GetContactPtrByNumber(n);
  315.         if (contact_ptr != nullptr) {
  316.             map_number_.erase(contact_ptr->GetNormalizedNumber());
  317.             contact_ptr->SetNumber(number);
  318.             map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
  319.         }
  320.     }
  321.  
  322.     void SetAddressByNumber(const std::string& address, const std::string& n) {
  323.         auto contact_ptr = GetContactPtrByNumber(n);
  324.         if (contact_ptr != nullptr) {
  325.             contact_ptr->SetAddress(address);
  326.         }
  327.     }
  328.  
  329.     void SetContact(int id, const Contact& contact) {
  330.         if (!map_id_.count(id)) {
  331.             return;
  332.         }
  333.         if (map_name_.count(contact.GetNormalizedName()) &&
  334.             map_name_[contact.GetNormalizedName()]->GetId() != id) {
  335.             return;
  336.         }
  337.         if (map_number_.count(contact.GetNormalizedNumber()) &&
  338.             map_number_[contact.GetNormalizedNumber()]->GetId() != id) {
  339.             return;
  340.         }
  341.         auto name = map_id_[id]->GetNormalizedName();
  342.         auto number = map_id_[id]->GetNormalizedNumber();
  343.         map_name_.erase(name);
  344.         map_number_.erase(number);
  345.         map_id_[id]->SetName(contact.GetName());
  346.         map_id_[id]->SetNumber(contact.GetNumber());
  347.         map_id_[id]->SetAddress(contact.GetAddress());
  348.         map_name_[contact.GetNormalizedName()] = map_id_[id];
  349.         map_number_[contact.GetNormalizedNumber()] = map_id_[id];
  350.     }
  351.  
  352.     void DeleteContact(int id) {
  353.         if (map_id_.count(id) == 0) {
  354.             return;
  355.         }
  356.         auto name = map_id_[id]->GetNormalizedName();
  357.         auto number = map_id_[id]->GetNormalizedNumber();
  358.         delete map_id_[id];
  359.         map_id_.erase(id);
  360.         map_name_.erase(name);
  361.         map_number_.erase(number);
  362.     }
  363. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement