vadimk772336

Untitled

Nov 24th, 2021 (edited)
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.05 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. this->second_tables[i].resize(second_table_size);
  123.  
  124. a = rand_int(1, p - 1);
  125. b = rand_int(0, p - 1); // i-ая ХФ для второго слоя
  126.  
  127. //Для каждого ключа в ячейке генерю хэш и отправляю в соот табл
  128. for (int j = 0; j < b_i; ++j)
  129. {
  130. key = nodes[i].keys[j];
  131. hash = uni_hash(a, b, second_table_size, key);
  132. this->second_tables[i][hash] = key;
  133. }
  134.  
  135. //Теперь проверяю на коллизции
  136. int z = 0; //Равно числу коллизций
  137. for (int k = 0; k < second_table_size; ++k)
  138. {
  139. //тут надо как то понять что уже такое встречалось
  140. // if ()
  141. // z++;
  142. // break;
  143. }
  144.  
  145. if (z == 0)
  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 < nodes.size(); ++i)
  186. {
  187. cout << "i= " << i << " : ";
  188. for (int j = 0; j < nodes[i].keys.size(); ++j)
  189. cout << 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