Advertisement
shchuko

5d

Nov 16th, 2019
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.41 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <cmath>
  5. #include <new>
  6.  
  7. class LinkedList {
  8. public:
  9.     class LinkedListNode {
  10.     public:
  11.         std::string key = "";
  12.  
  13.         LinkedListNode* p_prev = nullptr;
  14.         LinkedListNode* p_next = nullptr;
  15.  
  16.         LinkedListNode* p_prev_enter = nullptr;
  17.         LinkedListNode* p_next_enter = nullptr;
  18.     };
  19.  
  20.     bool add(const std::string &key, LinkedListNode* &last_enter_ptr);
  21.  
  22.     bool remove(const std::string &key, LinkedListNode* &last_enter_ptr);
  23.  
  24.     long size();
  25.  
  26.     ~LinkedList();
  27.  
  28. private:
  29.     LinkedListNode* p_begin = nullptr;
  30.     LinkedListNode* p_end = nullptr;
  31.     long list_size = 0;
  32.  
  33.     LinkedListNode* findKey(const std::string &key);
  34. };
  35.  
  36. class LinkedHashTable {
  37. public:
  38.     LinkedHashTable() = default;
  39.  
  40.     explicit LinkedHashTable(long size);
  41.  
  42.     ~LinkedHashTable();
  43.  
  44.     bool setSize(long size);
  45.  
  46.     void add(const std::string &key);
  47.  
  48.     bool remove(const std::string &key);
  49.  
  50.     const LinkedList::LinkedListNode* getLastEnterPtr();
  51.  
  52.     const long getElementsCount();
  53.  
  54. private:
  55.     LinkedList* table = nullptr;
  56.     long table_size = 0;
  57.     const double A = (sqrt(5) - 1) / 2;
  58.  
  59.     LinkedList::LinkedListNode* prev_enter_ptr = nullptr;
  60.     long elements_count = 0;
  61.  
  62.     long hash(const std::string &key) {
  63.         int keyVal = 0;
  64.         for (int i = 0; i < key.length(); ++i) {
  65.             keyVal += key[i] * (i + 1);
  66.         }
  67.         keyVal *= key.length() + 1;
  68.  
  69.         double int_part;
  70.         return (long)(table_size * modf(keyVal * A, &int_part));
  71.     }
  72. };
  73.  
  74. class List {
  75. public:
  76.     explicit List(long _element_map_size);
  77.  
  78.     ~List();
  79.  
  80.     void add(const std::string &key, const std::string &value);
  81.  
  82.     void removeAll(const std::string &key);
  83.  
  84.     void removePair(const std::string &key, const std::string &value);
  85.  
  86.     const LinkedList::LinkedListNode* getLastEnterPtr(const std::string &key);
  87.  
  88.     const long getElementsCount(const std::string &key);
  89.  
  90.     long size();
  91.  
  92. private:
  93.     class Node {
  94.     public:
  95.         std::string key = "";
  96.         LinkedHashTable linked_map;
  97.         Node* p_prev = nullptr;
  98.         Node* p_next = nullptr;
  99.  
  100.         explicit Node(long map_size) {
  101.             linked_map.setSize(map_size);
  102.         }
  103.     };
  104.  
  105.     Node* p_begin = nullptr;
  106.     Node* p_end = nullptr;
  107.     long list_size = 0;
  108.     long element_map_size = 0;
  109.  
  110.     Node* findKey(const std::string &_key);
  111. };
  112.  
  113. class HashMultiMap {
  114. public:
  115.     explicit HashMultiMap(long _level_first_size, long _level_second_size);
  116.  
  117.     ~HashMultiMap();
  118.  
  119.     void addPair(const std::string &key, const std::string &value);
  120.  
  121.     void removeAll(const std::string &key);
  122.  
  123.     void removePair(const std::string &key, const std::string &value);
  124.  
  125.  
  126.     const LinkedList::LinkedListNode* getLastEnterPtr(const std::string &key);
  127.  
  128.     const long getElementsCount(const std::string &key);
  129.  
  130. private:
  131.     List* table = nullptr;
  132.     long level_first_size = 0;
  133.     long level_second_size = 0;
  134.  
  135.     const double A = (sqrt(5) - 1) / 2;
  136.  
  137.     long hash(const std::string &_key);
  138. };
  139.  
  140. // LinkedList class methods
  141. LinkedList::~LinkedList() {
  142.     LinkedListNode* p_look = p_begin;
  143.     while (p_look != nullptr) {
  144.         LinkedListNode* temp = p_look;
  145.         p_look = p_look->p_next;
  146.         delete(temp);
  147.     }
  148.  
  149.     p_begin = nullptr;
  150.     p_end = nullptr;
  151. }
  152.  
  153. LinkedList::LinkedListNode *LinkedList::findKey(const std::string &key) {
  154.     if (!list_size)
  155.         return nullptr;
  156.  
  157.     LinkedListNode *p_look = p_begin;
  158.     while (p_look != nullptr && p_look->key != key)
  159.         p_look = p_look->p_next;
  160.     return p_look;
  161. }
  162.  
  163. bool LinkedList::add(const std::string &key, LinkedList::LinkedListNode *&last_enter_ptr) {
  164.     LinkedListNode* ptr_temp = findKey(key);
  165.     if (ptr_temp != nullptr)
  166.         return false;
  167.  
  168.     list_size++;
  169.     auto* temp = new LinkedListNode;
  170.     temp->key = key;
  171.  
  172.     temp->p_prev_enter = last_enter_ptr;
  173.     if (last_enter_ptr != nullptr)
  174.         last_enter_ptr->p_next_enter = temp;
  175.  
  176.     if (p_end == nullptr) {
  177.         p_begin = temp;
  178.         p_end = temp;
  179.         last_enter_ptr=  p_end;
  180.         return true;
  181.     }
  182.  
  183.     temp->p_prev = p_end;
  184.     p_end->p_next = temp;
  185.     p_end = temp;
  186.     last_enter_ptr = p_end;
  187.     return true;
  188.  
  189. }
  190.  
  191. bool LinkedList::remove(const std::string &key, LinkedList::LinkedListNode *&last_enter_ptr) {
  192.     LinkedListNode* ptr_temp = findKey(key);
  193.     if (ptr_temp == nullptr)
  194.         return false;
  195.  
  196.     if (ptr_temp == last_enter_ptr)
  197.         last_enter_ptr = ptr_temp->p_prev_enter;
  198.  
  199.     if (ptr_temp == p_begin)
  200.         p_begin = ptr_temp->p_next;
  201.     if (ptr_temp == p_end)
  202.         p_end = ptr_temp->p_prev;
  203.  
  204.     if (ptr_temp->p_prev != nullptr)
  205.         ptr_temp->p_prev->p_next = ptr_temp->p_next;
  206.     if (ptr_temp->p_next != nullptr)
  207.         ptr_temp->p_next->p_prev = ptr_temp->p_prev;
  208.  
  209.     if (ptr_temp->p_prev_enter != nullptr)
  210.         ptr_temp->p_prev_enter->p_next_enter = ptr_temp->p_next_enter;
  211.     if (ptr_temp->p_next_enter != nullptr)
  212.         ptr_temp->p_next_enter->p_prev_enter = ptr_temp->p_prev_enter;
  213.  
  214.     delete(ptr_temp);
  215.     --list_size;
  216.  
  217.     return true;
  218. }
  219.  
  220. long LinkedList::size() {
  221.     return list_size;
  222. }
  223.  
  224. // LinkedHashTableClassMethods
  225. LinkedHashTable::LinkedHashTable(long size) {
  226.     table = new LinkedList[size];
  227.     table_size = size;
  228. }
  229.  
  230. LinkedHashTable::~LinkedHashTable() {
  231.     delete[](table);
  232.     table = nullptr;
  233. }
  234.  
  235. bool LinkedHashTable::setSize(long size) {
  236.     // You can call this function only one time, no support for resize()
  237.     if (!table_size) {
  238.         table_size = size;
  239.         table = new LinkedList[size];
  240.         return true;
  241.     }
  242.     return false;
  243. }
  244.  
  245. void LinkedHashTable::add(const std::string &key) {
  246.     if (table[hash(key)].add(key, prev_enter_ptr))
  247.         ++elements_count;
  248. }
  249.  
  250. bool LinkedHashTable::remove(const std::string &key) {
  251.     if (table[hash(key)].remove(key, prev_enter_ptr))
  252.         --elements_count;
  253.     return elements_count == 0;
  254. }
  255.  
  256. const LinkedList::LinkedListNode *LinkedHashTable::getLastEnterPtr() {
  257.     return prev_enter_ptr;
  258. }
  259.  
  260. const long LinkedHashTable::getElementsCount() {
  261.     return elements_count;
  262. }
  263.  
  264. // List class methods
  265. List::List(long _element_map_size) {
  266.     element_map_size = _element_map_size;
  267. }
  268.  
  269. List::~List() {
  270.     Node* p_look = p_begin;
  271.     while (p_look != nullptr) {
  272.         Node* temp = p_look;
  273.         p_look = p_look->p_next;
  274.         delete(temp);
  275.     }
  276.  
  277.     p_begin = nullptr;
  278.     p_end = nullptr;
  279. }
  280.  
  281. void List::add(const std::string &key, const std::string &value) {
  282.     Node* ptr_temp = findKey(key);
  283.     if (ptr_temp == nullptr) {
  284.         list_size++;
  285.         auto* temp = new Node(element_map_size);
  286.         temp->key = key;
  287.         temp->linked_map.add(value);
  288.  
  289.         if (p_end == nullptr) {
  290.             p_begin = temp;
  291.             p_end = temp;
  292.             return;
  293.         }
  294.  
  295.         temp->p_prev = p_end;
  296.         p_end->p_next = temp;
  297.         p_end = temp;
  298.         return;
  299.     }
  300.  
  301.     ptr_temp->linked_map.add(value);
  302. }
  303.  
  304. void List::removeAll(const std::string &key) {
  305.     Node* ptr_temp = findKey(key);
  306.     if (ptr_temp == nullptr)
  307.         return;
  308.  
  309.     if (ptr_temp == p_begin)
  310.         p_begin = ptr_temp->p_next;
  311.     if (ptr_temp == p_end)
  312.         p_end = ptr_temp->p_prev;
  313.  
  314.     if (ptr_temp->p_prev != nullptr)
  315.         ptr_temp->p_prev->p_next = ptr_temp->p_next;
  316.     if (ptr_temp->p_next != nullptr)
  317.         ptr_temp->p_next->p_prev = ptr_temp->p_prev;
  318.  
  319.     delete(ptr_temp);
  320.     --list_size;
  321. }
  322.  
  323. void List::removePair(const std::string &key, const std::string &value) {
  324.     Node* ptr_temp = findKey(key);
  325.     if (ptr_temp == nullptr)
  326.         return;
  327.     if (ptr_temp->linked_map.remove(value))
  328.         removeAll(key);
  329. }
  330.  
  331. const LinkedList::LinkedListNode *List::getLastEnterPtr(const std::string &key) {
  332.     Node* ptr_temp = findKey(key);
  333.     if (ptr_temp == nullptr)
  334.         return nullptr;
  335.     return ptr_temp->linked_map.getLastEnterPtr();
  336. }
  337.  
  338. const long List::getElementsCount(const std::string &key) {
  339.     Node* ptr_temp = findKey(key);
  340.     if (ptr_temp == nullptr)
  341.         return 0;
  342.     return ptr_temp->linked_map.getElementsCount();
  343. }
  344.  
  345. long List::size() {
  346.     return list_size;
  347. }
  348.  
  349. List::Node *List::findKey(const std::string &_key) {
  350.     if (!list_size)
  351.         return nullptr;
  352.  
  353.     Node *p_look = p_begin;
  354.     while (p_look != nullptr && p_look->key != _key)
  355.         p_look = p_look->p_next;
  356.     return p_look;
  357. }
  358.  
  359. // HashMultiMap class methods
  360. HashMultiMap::HashMultiMap(long _level_first_size, long _level_second_size) {
  361.     level_first_size = _level_first_size;
  362.     level_second_size = _level_second_size;
  363.  
  364.     table = static_cast<List*>(operator new[] (level_first_size * sizeof(List)));
  365.     for (long i = 0; i < level_first_size; i++) {
  366.         new (table + i) List(level_second_size);
  367.     }
  368. }
  369.  
  370. HashMultiMap::~HashMultiMap() {
  371.     for (long i = 0; i < level_first_size; i++)
  372.         table[i].~List();
  373.  
  374.     operator delete[] (table);
  375.     table = nullptr;
  376. }
  377.  
  378. void HashMultiMap::addPair(const std::string &key, const std::string &value) {
  379.     long hash_value = hash(key);
  380.     table[hash_value].add(key, value);
  381. }
  382.  
  383. void HashMultiMap::removeAll(const std::string &key) {
  384.     table[hash(key)].removeAll(key);
  385. }
  386.  
  387. const LinkedList::LinkedListNode *HashMultiMap::getLastEnterPtr(const std::string &key) {
  388.     return table[hash(key)].getLastEnterPtr(key);
  389. }
  390.  
  391. void HashMultiMap::removePair(const std::string &key, const std::string &value) {
  392.     table[hash(key)].removePair(key, value);
  393. }
  394.  
  395. const long HashMultiMap::getElementsCount(const std::string &key) {
  396.     return table[hash(key)].getElementsCount(key);
  397. }
  398.  
  399. long HashMultiMap::hash(const std::string &_key) {
  400.     int keyVal = 0;
  401.     for (int i = 0; i < _key.length(); ++i) {
  402.         keyVal += _key[i] * (i + 1);
  403.     }
  404.     keyVal *= _key.length() + 1;
  405.  
  406.     double int_part;
  407.     return (long)(level_first_size * modf(keyVal * A, &int_part));
  408. }
  409.  
  410. #define IN_FILE_NAME "multimap.in"
  411. #define OUT_FILE_NAME "multimap.out"
  412.  
  413. using std::ifstream;
  414. using std::ofstream;
  415. using std::string;
  416.  
  417. int main() {
  418.     ifstream fin(IN_FILE_NAME);
  419.     if (!fin.is_open())
  420.         return 2;
  421.     ofstream fout(OUT_FILE_NAME);
  422.     if (!fout.is_open())
  423.         return 2;
  424.  
  425.     HashMultiMap multi_map(1000, 200);
  426.     while (true) {
  427.         string command;
  428.         fin >> command;
  429.         if (command.empty())
  430.             break;
  431.  
  432.         string key;
  433.         fin >> key;
  434.         if (command == "put") {
  435.             string value;
  436.             fin >> value;
  437.             multi_map.addPair(key, value);
  438.         }
  439.         else if (command == "delete") {
  440.             string value;
  441.             fin >> value;
  442.             multi_map.removePair(key, value);
  443.         }
  444.         else if (command == "deleteall") {
  445.             multi_map.removeAll(key);
  446.         }
  447.         else if (command == "get") {
  448.             fout << multi_map.getElementsCount(key) << ' ';
  449.  
  450.             auto* element_ptr = (LinkedList::LinkedListNode*)multi_map.getLastEnterPtr(key);
  451.             while (element_ptr != nullptr) {
  452.                 fout << element_ptr->key << ' ';
  453.                 element_ptr = element_ptr->p_prev_enter;
  454.             }
  455.             fout << '\n';
  456.         }
  457.     }
  458.  
  459.     return 0;
  460. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement