vadimk772336

c принтаами

Nov 24th, 2021 (edited)
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.65 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. cout << "Задаём размеры таблиц " << endl;
  63. this->nodes.resize(table_size);
  64. this->second_tables.resize(table_size); //внутренние размера 0
  65.  
  66. int hash, key;
  67. bool flag = false; //Тру если простроили корректно
  68. int a,b;
  69.  
  70. cout << "Сейчас начну вайл для 1 уровня " << endl;
  71. while (!flag)
  72.  
  73. {
  74. a = rand_int(1, p - 1);
  75. b = rand_int(0, p - 1); //Глобальная ХФ
  76.  
  77. cout << "Сгенерил ХФ, закидываю ключи в табл " << endl;
  78. //Закинули все ключи в таблицу
  79. for (int i = 0; i < this->count_numbers; ++i)
  80. {
  81. key = numbers[i];
  82. hash = uni_hash(a, b, table_size, key);
  83. nodes[hash].keys.push_back(key);
  84. nodes[hash].count_keys += 1;
  85. }
  86.  
  87. cout << "Теперь считаю коллизии " << endl;
  88. //Теперь считаю коллизии
  89. int S = 0;
  90. for (int i = 0; i < this->table_size; ++i)
  91. {
  92. S += (nodes[i].count_keys) * (nodes[i].count_keys);
  93. }
  94.  
  95. if (this->table_size >= S) //Влезаем в линейный объем на 2 уровне
  96. {
  97. cout << "По размеру подошли - оставляю " << endl;
  98. flag = true;
  99. }
  100.  
  101. else //Чистка
  102. {
  103. cout << "Не подошло по размеру начинаю снова " << endl;
  104. this->nodes.clear();
  105. nodes.resize(this->table_size);
  106. }
  107. }
  108.  
  109. //Запомнили значение полученной глобальной функции
  110. this->main_a = a;
  111. this->main_b = b;
  112. cout << "Запомнили значение полученной глобальной функции " << endl;
  113. //Вышли из вайл - значит успешно построили первый уровень, теперь второй:
  114.  
  115. int b_i; //Число элементов в ячейке i
  116. int second_table_size;
  117.  
  118. cout << "теперь второй: для каждой ячейки не пустой строим ХФ без коллизий " << endl;
  119. for (int i = 0; i < this->table_size; ++i) //Для каждой ячейки не пустой строим ХФ без коллизий
  120. {
  121. cout << "---------- i= " << i << endl;
  122. b_i = nodes[i].count_keys;
  123. if (b_i > 0) //Если там есть хоть 1 ключ то строим иначе зачем?
  124. {
  125. cout << "в b_i есть хоть 1 ключ, начинаем для него строить хф 2 уровня " << endl;
  126. flag = false;
  127. while (!flag) //Повторяю попытки пока не получится без коллизий (добавить проврку на
  128. //пустоту)
  129. {
  130. cout << "зашёл в вайл " << endl;
  131. second_table_size = b_i * b_i * c;
  132.  
  133. //создать таблицу второго уровня для данного ключ
  134. //Кладу по умолчанию p чтобы понять что лежит там мусор или ключ
  135. cout << "создал таблицу 2 уровня " << endl;
  136. this->second_tables[i].resize(second_table_size, p);
  137.  
  138. a = rand_int(1, p - 1);
  139. b = rand_int(0, p - 1); // i-ая ХФ для второго слоя
  140.  
  141. cout << "созжад ХФ, Для каждого ключа в ячейке генерю хэш и отправляю в соот табл" << endl;
  142. //Для каждого ключа в ячейке генерю хэш и отправляю в соот табл
  143. bool there_is_collis = false;
  144. for (int j = 0; j < b_i; ++j)
  145. {
  146. key = nodes[i].keys[j];
  147. hash = uni_hash(a, b, second_table_size, key);
  148.  
  149. //Проверка что там изначально пусто (нет коллизии)
  150. if (this->second_tables[i][hash] != p)
  151. {
  152. cout << "нашлась коллизия, всё по новой" << endl;
  153. there_is_collis = true;
  154. break;
  155. }
  156.  
  157. this->second_tables[i][hash] = key;
  158. }
  159.  
  160. if (!there_is_collis)
  161. {
  162. cout << "коллизий нет - готово!" << endl;
  163. flag = true;
  164. this->nodes[i].a = a; //Запоминаю полученную ХФ beta_i
  165. this->nodes[i].b = b;
  166. this->nodes[i].second_table = &(this->second_tables[i]); //Мб не надо
  167. this->nodes[i].second_table_size = second_table_size;
  168. }
  169. }
  170. }
  171. }
  172.  
  173. print();
  174. cout << "Конец Initialize!" << endl;
  175. }
  176.  
  177. bool FixedSet::Contains(int number) const
  178. {
  179. int hash_1, hash_2, a, b;
  180. int key;
  181.  
  182. a = this->main_a;
  183. b = this->main_b;
  184. hash_1 = uni_hash(a, b, table_size, number);
  185.  
  186. Node node;
  187. node = this->nodes[hash_1];
  188.  
  189. int a_k, b_k;
  190. a_k = node.a;
  191. b_k = node.b;
  192. int second_table_size = node.second_table_size;
  193.  
  194. hash_2 = uni_hash(a_k, b_k, second_table_size, number);
  195. //key = node.second_table[hash_2];
  196. key = second_tables[hash_1][hash_2];
  197.  
  198. return (key == number);
  199. }
  200.  
  201. void FixedSet::print()
  202. {
  203. cout << "\n print: \n";
  204. for (int i = 0; i < this->nodes.size(); ++i)
  205. {
  206. cout << "i= " << i << " : ";
  207. for (int j = 0; j < this->nodes[i].second_table_size; ++j)
  208. cout << second_tables[i][j] << " ";
  209. cout << endl;
  210. }
  211. cout << "end print" << endl;
  212. }
  213.  
  214. int main()
  215. {
  216.  
  217. FixedSet f;
  218.  
  219. vector<int> numbers = { 1, 2, 3 };
  220. f.Initialize(numbers);
  221. //f.print();
  222.  
  223.  
  224. return 0;
  225. }
  226.  
Add Comment
Please, Sign In to add comment