vadimk772336

Untitled

Nov 24th, 2021
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.11 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cstdlib> // для функций rand() и srand()
  4. #include <list>
  5. #include <iterator>
  6. using namespace std;
  7.  
  8. const int c = 3; // O(n) ~ 3n
  9. const int p = 2000000033;
  10.  
  11. int rand_int(int min, int max)
  12. {
  13. static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);
  14. return static_cast<int>(rand() * fraction * (max - min + 1) + min);
  15. }
  16.  
  17. int uni_hash(int a, int b, int m, int key)
  18. {
  19. return ((a * key + b) % p) % m;
  20. }
  21.  
  22.  
  23. struct Node
  24. {
  25. int a;
  26. int b;
  27. vector<int>* second_table = NULL;
  28. int second_table_size = 0;
  29. vector<int> keys;
  30. int count_keys = 0;
  31. };
  32.  
  33. class FixedSet
  34. {
  35. vector<struct Node> nodes; //вектор ячеек первой хэш табл
  36. vector<vector<int>> second_tables; //вектор хэш таблиц второго уровня
  37. int count_numbers;
  38. int table_size;
  39. int main_a;
  40. int main_b;
  41. // vector<vector<int>> vec(2, vector<int>(10));
  42. public:
  43. FixedSet();
  44. void Initialize(const vector<int>& numbers);
  45. bool Contains(int number) const;
  46. void print();
  47. };
  48.  
  49. FixedSet::FixedSet()
  50. {
  51. this->count_numbers = 0;
  52. this->nodes;
  53. this->table_size = 0;
  54. }
  55.  
  56. void FixedSet::Initialize(const vector<int>& numbers)
  57. {
  58. this->count_numbers = numbers.size();
  59. this->table_size = c * count_numbers;
  60.  
  61. //Задаём размеры таблиц
  62. this->nodes.resize(table_size);
  63. this->second_tables.resize(table_size); //внутренние размера 0
  64.  
  65. int hash, key;
  66. bool flag = false; //Тру если простроили корректно
  67. int a, b;
  68. while (!flag)
  69.  
  70. {
  71. a = rand_int(1, p - 1);
  72. b = rand_int(0, p - 1); //Глобальная ХФ
  73.  
  74. //Закинули все ключи в таблицу
  75. for (int i = 0; i < this->count_numbers; ++i)
  76. {
  77. key = numbers[i];
  78. hash = uni_hash(a, b, table_size, key);
  79. nodes[hash].keys.push_back(key);
  80. nodes[hash].count_keys += 1;
  81. }
  82.  
  83. //Теперь считаю коллизии
  84. int S = 0;
  85. for (int i = 0; i < this->table_size; ++i)
  86. {
  87. S += (nodes[i].count_keys) * (nodes[i].count_keys);
  88. }
  89.  
  90. if (this->table_size >= S) //Влезаем в линейный объем на 2 уровне
  91. {
  92. flag = true;
  93. }
  94.  
  95. else //Чистка
  96. {
  97. this->nodes.clear();
  98. nodes.resize(this->table_size);
  99. }
  100. }
  101.  
  102. //Запомнили значение полученной глобальной функции
  103. this->main_a = a;
  104. this->main_b = b;
  105.  
  106. //Вышли из вайл - значит успешно построили первый уровень, теперь второй:
  107.  
  108. int b_i; //Число элементов в ячейке i
  109. int second_table_size;
  110. for (int i = 0; i < this->table_size; ++i) //Для каждой ячейки не пустой строим ХФ без коллизий
  111. {
  112. b_i = nodes[i].count_keys;
  113. if (b_i > 0) //Если там есть хоть 1 ключ то строим иначе зачем?
  114. {
  115. flag = false;
  116. while (!flag) //Повторяю попытки пока не получится без коллизий (добавить проврку на
  117. //пустоту)
  118. {
  119. second_table_size = b_i * b_i * c;
  120.  
  121. //создать таблицу второго уровня для данного ключ
  122. //Кладу по умолчанию p чтобы понять что лежит там мусор или ключ
  123. this->second_tables[i].resize(second_table_size, p);
  124.  
  125. a = rand_int(1, p - 1);
  126. b = rand_int(0, p - 1); // i-ая ХФ для второго слоя
  127.  
  128. //Для каждого ключа в ячейке генерю хэш и отправляю в соот табл
  129. bool there_is_collis = false;
  130. for (int j = 0; j < b_i; ++j)
  131. {
  132. key = nodes[i].keys[j];
  133. hash = uni_hash(a, b, second_table_size, key);
  134.  
  135. //Проверка что там изначально пусто (нет коллизии)
  136. if (this->second_tables[i][hash] != p)
  137. {
  138. there_is_collis = true;
  139. break;
  140. }
  141.  
  142. this->second_tables[i][hash] = key;
  143. }
  144.  
  145. if (!there_is_collis)
  146. {
  147. flag = true;
  148. this->nodes[i].a = a; //Запоминаю полученную ХФ beta_i
  149. this->nodes[i].b = b;
  150. this->nodes[i].second_table = &(this->second_tables[i]); //Мб не надо
  151. this->nodes[i].second_table_size = second_table_size;
  152. }
  153. }
  154. }
  155. }
  156. }
  157.  
  158. bool FixedSet::Contains(int number) const
  159. {
  160. int hash_1, hash_2, a, b;
  161. int key;
  162.  
  163. a = this->main_a;
  164. b = this->main_b;
  165. hash_1 = uni_hash(a, b, table_size, number);
  166.  
  167. Node node;
  168. node = this->nodes[hash_1];
  169.  
  170. int a_k, b_k;
  171. a_k = node.a;
  172. b_k = node.b;
  173. int second_table_size = node.second_table_size;
  174.  
  175. hash_2 = uni_hash(a_k, b_k, second_table_size, number);
  176. // key = node.second_table[hash_2];
  177. key = second_tables[hash_1][hash_2];
  178.  
  179. return (key == number);
  180. }
  181.  
  182. void FixedSet::print()
  183. {
  184. cout << "\n print: \n";
  185. for (int i = 0; i < this->nodes.size(); ++i)
  186. {
  187. cout << "i= " << i << " : ";
  188. for (int j = 0; j < this->nodes[i].keys.size(); ++j)
  189. cout << this->nodes[i].keys[j] << endl;
  190. }
  191. cout << endl;
  192. }
  193.  
  194. int main()
  195. {
  196. cout << "Hello World";
  197. FixedSet f;
  198.  
  199. vector<int> numbers = { 1, 2, 3 };
  200. f.Initialize(numbers);
  201. // f.print();
  202.  
  203.  
  204. return 0;
  205. }
  206.  
Advertisement
Add Comment
Please, Sign In to add comment