Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <optional>
- #include <cassert>
- #include <vector>
- #include <algorithm>
- #include <cctype>
- #include <unordered_map>
- struct Number {
- std::string number_ = "";
- Number() = default;
- explicit Number(const std::string& number) : number_(number) {}
- std::string GetNormalizedString() const {
- return number_[0] == '+' ? number_.substr(1, number_.length() - 1) : number_;
- }
- };
- struct Address {
- std::optional<std::string> address_;
- Address() = default;
- explicit Address(const std::string& address) {
- address_.emplace(address);
- }
- std::string GetNormalizedString() const {
- return address_.has_value() ? address_.value() : "";
- }
- };
- struct Name {
- std::string name_ = "";
- Name() = default;
- explicit Name(const std::string& name) : name_(name){}
- std::string GetNormalizedString() const {
- std::vector<std::string> vector;
- int j = -1;
- for (size_t i = 0; i < name_.length(); ++i) {
- if (!isalpha(name_[i])) {
- if (i != j + 1) {
- vector.push_back(name_.substr(j + 1, i - j - 1));
- }
- j = i;
- }
- }
- if (j + 1 != name_.length()) {
- vector.push_back(name_.substr(j + 1, name_.length() - j));
- }
- for (auto &elem : vector) {
- for (auto &ch : elem) {
- ch = tolower(ch);
- }
- }
- std::sort(vector.begin(), vector.end());
- std::string res;
- for (const auto &elem : vector) {
- res += elem;
- res += " ";
- }
- return res.empty() ? res : res.substr(0, res.length() - 1);
- }
- };
- class Contact {
- private:
- int id_;
- Name name_;
- Number number_;
- Address address_;
- public:
- Contact() : id_(-1), name_(Name()), number_(Number()), address_(Address()) {}
- Contact(int id, const std::string& name, const std::string& number, const std::string& address)
- : id_(id), name_(name), number_(number), address_(address){}
- Contact(const std::string& name, const std::string& number, const std::string& address)
- : id_(-1), name_(name), number_(number), address_(address){}
- int GetId() const {
- return id_;
- }
- std::string GetName() const {
- return name_.name_;
- }
- std::string GetNumber() const {
- return number_.number_;
- }
- std::string GetAddress() const {
- return address_.address_.has_value() ? address_.address_.value() : "";
- }
- void SetId(int id) {
- id_ = id;
- }
- void SetName(const std::string name) {
- name_.name_ = name;
- }
- void SetNumber(const std::string number) {
- number_.number_ = number;
- }
- void SetAddress(const std::string address) {
- address_.address_.emplace(address);
- }
- std::string GetNormalizedName() const {
- return name_.GetNormalizedString();
- }
- std::string GetNormalizedNumber() const {
- return number_.GetNormalizedString();
- }
- std::string GetNormalizedAddress() const {
- return address_.GetNormalizedString();
- }
- };
- class PhoneBook {
- private:
- std::unordered_map<int, Contact*> map_id_;
- std::unordered_map<std::string, Contact*> map_name_;
- std::unordered_map<std::string, Contact*> map_number_;
- int max_id_ = 0;
- Contact* GetContactPtrById(int id) const {
- if (map_id_.count(id) == 0) {
- return nullptr;
- }
- return map_id_.at(id);
- }
- Contact* GetContactPtrByName(const std::string& name) const {
- auto n = Name(name).GetNormalizedString();
- if (map_name_.count(n) == 0) {
- return nullptr;
- }
- return map_name_.at(n);
- }
- Contact* GetContactPtrByNumber(const std::string& number) const {
- auto n = Number(number).GetNormalizedString();
- if (map_number_.count(n) == 0) {
- return nullptr;
- }
- return map_number_.at(n);
- }
- public:
- PhoneBook() : max_id_(0) {}
- int AddContact(const std::string& name, const std::string& number, const std::string& address) {
- if (map_name_.count(Name(name).GetNormalizedString()) > 0 ||
- map_number_.count(Number(number).GetNormalizedString()) > 0) {
- return -1;
- }
- auto* contact = new Contact(max_id_++, name, number, address);
- map_id_[max_id_ - 1] = contact;
- map_name_[contact->GetNormalizedName()] = contact;
- map_number_[contact->GetNormalizedNumber()] = contact;
- return max_id_ - 1;
- }
- ~PhoneBook() {
- for (const auto& elem : map_id_) {
- delete elem.second;
- }
- }
- PhoneBook(const PhoneBook& rhs) : max_id_(rhs.max_id_) {
- for (const auto& elem : map_id_) {
- delete map_id_[elem.first];
- }
- map_id_.clear();
- map_name_.clear();
- map_number_.clear();
- for (const auto& elem : rhs.map_id_) {
- auto* contact = new Contact(elem.first, elem.second->GetName(), elem.second->GetNumber(),
- elem.second->GetAddress());
- map_id_[elem.first] = contact;
- map_name_[contact->GetNormalizedName()] = contact;
- map_number_[contact->GetNormalizedNumber()] = contact;
- }
- }
- PhoneBook& operator=(const PhoneBook& rhs) {
- if (this != &rhs) {
- max_id_ = rhs.max_id_;
- for (const auto& elem : map_id_) {
- delete map_id_[elem.first];
- }
- map_id_.clear();
- map_name_.clear();
- map_number_.clear();
- for (const auto& elem : rhs.map_id_) {
- auto* contact = new Contact(elem.first, elem.second->GetName(), elem.second->GetNumber(),
- elem.second->GetAddress());
- map_id_[elem.first] = contact;
- map_name_[contact->GetNormalizedName()] = contact;
- map_number_[contact->GetNormalizedNumber()] = contact;
- }
- }
- return *this;
- }
- PhoneBook(PhoneBook&& rhs) = default;
- PhoneBook& operator=(PhoneBook&& rhs) = default;
- std::vector<Contact> GetContactsByAddress(const std::string& address) const {
- std::vector<Contact> vector;
- for (const auto& elem : map_id_) {
- if (elem.second->GetNormalizedAddress().find(address) != std::string::npos) {
- vector.push_back(*elem.second);
- }
- }
- return vector;
- }
- Contact GetContactById(int id, bool* flag) const {
- auto contact_ptr = GetContactPtrById(id);
- *flag = contact_ptr != nullptr;
- return *flag ? *map_id_.at(id) : Contact();
- }
- void SetNameById(const std::string& name, int id) {
- auto contact_ptr = GetContactPtrById(id);
- if (contact_ptr != nullptr) {
- map_name_.erase(contact_ptr->GetNormalizedName());
- contact_ptr->SetName(name);
- map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
- }
- }
- void SetNumberById(const std::string& number, int id) {
- auto contact_ptr = GetContactPtrById(id);
- if (contact_ptr != nullptr) {
- map_number_.erase(contact_ptr->GetNormalizedNumber());
- contact_ptr->SetNumber(number);
- map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
- }
- }
- void SetAddressById(const std::string& address, int id) {
- auto contact_ptr = GetContactPtrById(id);
- if (contact_ptr != nullptr) {
- contact_ptr->SetAddress(address);
- }
- }
- Contact GetContactByName(const std::string& name, bool* flag) const {
- auto contact_ptr = GetContactPtrByName(name);
- *flag = contact_ptr != nullptr;
- return *flag ? *map_name_.at(name) : Contact();
- }
- void SetNameByName(const std::string& name, const std::string& n) {
- auto contact_ptr = GetContactPtrByName(n);
- if (contact_ptr != nullptr) {
- map_name_.erase(contact_ptr->GetNormalizedName());
- contact_ptr->SetName(name);
- map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
- }
- }
- void SetNumberByName(const std::string& number, const std::string& n) {
- auto contact_ptr = GetContactPtrByName(n);
- if (contact_ptr != nullptr) {
- map_number_.erase(contact_ptr->GetNormalizedNumber());
- contact_ptr->SetNumber(number);
- map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
- }
- }
- void SetAddressByName(const std::string& address, const std::string& n) {
- auto contact_ptr = GetContactPtrByName(n);
- if (contact_ptr != nullptr) {
- contact_ptr->SetAddress(address);
- }
- }
- Contact GetContactByNumber(const std::string& number, bool* flag) const {
- auto contact_ptr = GetContactPtrByNumber(number);
- *flag = contact_ptr != nullptr;
- return *flag ? *map_number_.at(number) : Contact();
- }
- void SetNameByNumber(const std::string& name, const std::string& n) {
- auto contact_ptr = GetContactPtrByNumber(n);
- if (contact_ptr != nullptr) {
- map_name_.erase(contact_ptr->GetNormalizedName());
- contact_ptr->SetName(name);
- map_name_[contact_ptr->GetNormalizedName()] = contact_ptr;
- }
- }
- void SetNumberByNumber(const std::string& number, const std::string& n) {
- auto contact_ptr = GetContactPtrByNumber(n);
- if (contact_ptr != nullptr) {
- map_number_.erase(contact_ptr->GetNormalizedNumber());
- contact_ptr->SetNumber(number);
- map_number_[contact_ptr->GetNormalizedNumber()] = contact_ptr;
- }
- }
- void SetAddressByNumber(const std::string& address, const std::string& n) {
- auto contact_ptr = GetContactPtrByNumber(n);
- if (contact_ptr != nullptr) {
- contact_ptr->SetAddress(address);
- }
- }
- void SetContact(int id, const Contact& contact) {
- if (!map_id_.count(id)) {
- return;
- }
- if (map_name_.count(contact.GetNormalizedName()) &&
- map_name_[contact.GetNormalizedName()]->GetId() != id) {
- return;
- }
- if (map_number_.count(contact.GetNormalizedNumber()) &&
- map_number_[contact.GetNormalizedNumber()]->GetId() != id) {
- return;
- }
- auto name = map_id_[id]->GetNormalizedName();
- auto number = map_id_[id]->GetNormalizedNumber();
- map_name_.erase(name);
- map_number_.erase(number);
- map_id_[id]->SetName(contact.GetName());
- map_id_[id]->SetNumber(contact.GetNumber());
- map_id_[id]->SetAddress(contact.GetAddress());
- map_name_[contact.GetNormalizedName()] = map_id_[id];
- map_number_[contact.GetNormalizedNumber()] = map_id_[id];
- }
- void DeleteContact(int id) {
- if (map_id_.count(id) == 0) {
- return;
- }
- auto name = map_id_[id]->GetNormalizedName();
- auto number = map_id_[id]->GetNormalizedNumber();
- delete map_id_[id];
- map_id_.erase(id);
- map_name_.erase(name);
- map_number_.erase(number);
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement