Advertisement
Guest User

Untitled

a guest
Dec 14th, 2018
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. /*Реализуйте структуру данных типа “множество строк”
  2. на основе динамической хеш-таблицы с открытой адресацией.
  3. Хранимые строки непустые и состоят из строчных латинских букв.
  4. Хеш-функция строки должна быть реализована с помощью вычисления значения многочлена методом Горнера.
  5. Начальный размер таблицы должен быть равным 8-ми.
  6. Перехеширование выполняйте при добавлении элементов в случае,
  7. когда коэффициент заполнения таблицы достигает 3/4.
  8. Структура данных должна поддерживать операции добавления строки в множество,
  9. удаления строки из множества и проверки принадлежности данной строки множеству.
  10. Для разрешения коллизий используйте двойное хеширование.*/
  11. #include <iostream>
  12. #include <vector>
  13.  
  14. class HashTable
  15. {
  16.     int N = 0; //количество элементов в хеш-таблице
  17.     int M = 8; //размер хеш-таблицы
  18.     double alpha(); //вычисляет коэффициент заполнения хеш-таблицы
  19.     unsigned int h1(std::string&); //первая хеш-функция для строки
  20.     unsigned int h2(std::string&); //вторая хеш-функция для строки
  21.     unsigned int h(std::string&, int); //хеш-функция с номером пробы
  22.     std::vector<std::pair<std::string, bool> > table; //таблицу храним как вектор пар (строка, флаг), где флаг указывает, удалена ли строка.
  23.     void rehash();
  24.     unsigned int string_search(std::string&); //возвращает хеш искомого элемента или М, если элемент не найден. Используется в search и erase.
  25. public:
  26.     HashTable(): table(M) {};
  27.     ~HashTable() = default;
  28.     bool insert(std::string&); //вставка элемента, возвращает true, если она успешна
  29.     bool search(std::string&); //поиск элемента, возвращает true, если элемент найден
  30.     bool erase(std::string&); //удаление элемента, возвращает false, если оно успешно
  31. };
  32.  
  33. unsigned int HashTable::h1(std::string &s)
  34. {
  35.     int Hash = int(s[0]);
  36.     for(int i = 1; i < s.size(); ++i)
  37.         Hash = Hash * 11719 + int(s[i]);//11719 - простое число.
  38.     return Hash;
  39. }
  40.  
  41. unsigned int HashTable::h2(std::string &s)
  42. {
  43.     int Hash = int(s[s.size() - 1]);
  44.     for(int i = s.size() - 2; i >= 0; --i)
  45.         Hash = Hash * 11719 + int(s[i]);
  46.     return 2 * Hash + 1; //использовано, чтобы возвращаемое значение было нечетным => взаимно простым с M
  47. }
  48.  
  49. unsigned int HashTable::h(std::string &s, int i)
  50. {
  51.     return (h1(s) + i * h2(s));
  52. }
  53.  
  54. double HashTable::alpha()
  55. {
  56.     return double(N) / double(M);
  57. }
  58.  
  59. void HashTable::rehash()
  60. {
  61.     std::vector<std::pair<std::string, bool> > new_table(2 * M);
  62.     unsigned int Hash;
  63.     for(int i = 0; i < M; ++i)
  64.         if (!table[i].first.empty())
  65.             for(int j = 0; j < 2 * M; ++j)
  66.             {
  67.                 Hash = h(table[i].first, j) % (2 * M);
  68.                 if (new_table[Hash].first.empty())
  69.                 {
  70.                     new_table[Hash].first = table[i].first;
  71.                     new_table[Hash].second = false;
  72.                     break;
  73.                 }
  74.             }
  75.     table.resize(2 * M);
  76.     M *= 2;
  77.     table = std::move(new_table); //таблица переносится на нужное место, при этом память не теряется.
  78. }
  79.  
  80. unsigned int HashTable::string_search(std::string &s)
  81. {
  82.     int m = M;
  83.     unsigned int Hash;
  84.     for(int i = 0; i < M; ++i)
  85.     {
  86.         Hash = h(s, i) % M;
  87.         if (table[Hash].first.empty() && !table[Hash].second)
  88.             break;
  89.         else
  90.             if (!table[Hash].second && s == table[Hash].first)
  91.             {
  92.                 m = Hash;
  93.                 break;
  94.             }
  95.     }
  96.     return m;
  97. }
  98.  
  99. bool HashTable::insert(std::string &s)
  100. {
  101.     unsigned int Hash;
  102.     bool f = false;
  103.     for(int i = 0; i < M; ++i)
  104.     {
  105.         Hash = h(s, i) % M;
  106.         if (table[Hash].first.empty())
  107.         {
  108.             f = true;
  109.             table[Hash].first = s;
  110.             table[Hash].second = false;
  111.             N++;
  112.             break;
  113.         }
  114.         else
  115.             if (!table[Hash].second && s == table[Hash].first)
  116.                 break;
  117.     }
  118.     if (alpha() >= double(3)/double(4)) rehash();
  119.     return f;
  120. }
  121.  
  122. bool HashTable::search(std::string &s)
  123. {
  124.     unsigned int Hash = string_search(s);
  125.     if (Hash == M)
  126.         return false;
  127.     return true;
  128. }
  129.  
  130. bool HashTable::erase(std::string &s)
  131. {
  132.     unsigned int Hash = string_search(s);
  133.     if (Hash == M)
  134.         return false;
  135.     table[Hash].first.clear();
  136.     table[Hash].second = true;
  137.     N--;
  138.     return true;
  139. }
  140.  
  141. int main()
  142. {
  143.     char c;
  144.     std::string s;
  145.     HashTable h;
  146.     while (std::cin >> c)
  147.     {
  148.         std::cin >> s;
  149.         if (c == '+')
  150.             if (h.insert(s))
  151.                 std::cout << "OK\n";
  152.             else
  153.                 std::cout << "FAIL\n";
  154.         if (c == '-')
  155.             if (h.erase(s))
  156.                 std::cout << "OK\n";
  157.             else
  158.                 std::cout << "FAIL\n";
  159.         if (c == '?')
  160.             if (h.search(s))
  161.                 std::cout << "OK\n";
  162.             else
  163.                 std::cout << "FAIL\n";
  164.     }
  165.     return 0;
  166. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement