Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <time.h>
- #include <stdlib.h>
- #include <random>
- std::string random_string() //generator losowych napisow 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
- {
- std::string str("abcdefghijklmnopqrstuvwxyz");
- std::random_device rd;
- std::mt19937 generator(rd());
- std::shuffle(str.begin(), str.end(), generator);
- return str.substr(0, 2);
- }
- template<typename T>
- class Node
- {
- public:
- std::string name;
- T data;
- std::string to_string()
- {
- return name + " " + std::to_string(data);
- }
- Node()
- {
- name = random_string();
- data = rand() % 100;
- }
- Node(std::string str, T data)
- {
- this->name = str;
- this->data = data;
- }
- bool operator==(Node* data)
- {
- if (this->data == data.data && this->name == data.name)
- return true;
- else
- return false;
- }
- bool operator==(std::string data)
- {
- if (this->name == data)
- return true;
- else
- return false;
- }
- };
- template<typename T>
- class List_Node
- {
- public:
- T data;
- List_Node* next;
- List_Node* prev;
- List_Node()
- {
- data = next = prev = NULL;
- }
- List_Node(T data)
- {
- this->data = data;
- next = prev = NULL;
- }
- ~List_Node()
- {
- }
- };
- template<typename T>
- class Lista
- {
- private:
- List_Node<T>* head;
- List_Node<T>* tail;
- public:
- int counter;
- Lista()
- {
- this->head = this->tail = NULL;
- this->counter = 0;
- }
- ~Lista()
- {
- List_Node<T>* node;
- while (this->head)
- {
- node = this->head->next;
- delete this->head;
- this->head = node;
- }
- }
- //Dodaje element <T> na poczatek listy
- void add_Front(T data)
- {
- List_Node<T>* node = new List_Node<T>(data);
- if (this->head)
- {
- node->next = this->head;
- node->prev = NULL;
- this->head->prev = node;
- this->head = node;
- }
- else
- this->head = this->tail = node;
- this->counter++;
- }
- //Dodaje element <T> na koniec listy
- List_Node<T>* add_Back(T data)
- {
- List_Node<T>* node = new List_Node<T>(data);
- if (this->head)
- {
- node->prev = this->tail;
- node->next = NULL;
- this->tail->next = node;
- this->tail = node;
- }
- else
- this->head = this->tail = node;
- this->counter++;
- return node;
- }
- //Dodaje elementy z zachowaniem kolajnosci
- List_Node<T>* add_Order(T dane)
- {
- List_Node<T>* new_node = new List_Node<T>(dane);
- if (this->head)
- {
- List_Node<T>* tmp;
- tmp = this->head;
- T* tmp_data = tmp->data;
- if (*tmp_data == dane == 0)//sprawdzam czy klucze sa takie same
- {
- std::cout << "Takie same indeksy" << std::endl;
- return NULL;
- }
- else if ((*tmp_data == dane) > 0)
- return this->add_Front(dane);
- tmp = this->head->next; //przechodze do nastepnego elementu
- if (tmp)
- tmp_data = tmp->data;
- while (tmp)
- {
- if ((*tmp_data == dane) == 0)
- {
- std::cout << "Takie same indeksy" << std::endl;
- return NULL;
- }
- else if ((*tmp_data == dane) > 0) //wstawianie przed
- {
- new_node->prev = tmp->prev;
- tmp->prev->next = new_node;
- new_node->next = tmp;
- tmp->prev = new_node;
- this->counter++;
- return new_node;
- }
- tmp = tmp->next;
- if (tmp)
- tmp_data = tmp->data;
- }
- return this->add_Back(dane);
- }
- else
- return this->add_Front(dane);
- }
- //Usuwa z listy pierwszy element z listy nie usuwajac <T> i zwraca wskaznk na dane
- T del_Front()
- {
- if (this->head)
- {
- List_Node<T>* node = this->head;
- T node_data = node->data;
- this->head = this->head->next;
- node->next = NULL;
- node->data = NULL;
- delete node;
- if (this->head)
- this->head->prev = NULL;
- else
- this->tail = NULL;
- this->counter--;
- return node_data;
- }
- else return NULL;
- }
- //Usuwa z ostatni pierwszy element z listy nie usuwajac <T> i zwraca wskaznk na dane
- T del_Back()
- {
- if (this->head)
- {
- List_Node<T>* node = this->tail;
- T node_data = node->data;
- this->tail = this->tail->prev;
- node->prev = NULL;
- node->data = NULL;
- delete node;
- if (this->tail)
- this->tail->next = NULL;
- else
- this->head = NULL;
- this->counter--;
- return node_data;
- }
- else return NULL;
- }
- //Usuwa cala liste (true usuwa tez wartosci z <T>, false czysci liste)
- void delete_(bool a)
- {
- if (a)
- {
- while (this->head)
- delete this->del_Front();
- }
- else
- {
- while (this->head)
- this->del_Front();
- }
- }
- //Usuwa element po wskazniku List_Node<T>
- T del(List_Node<T>* node)
- {
- if (node == this->head)
- return this->del_Front();
- else if (node == this->tail)
- return this->del_Back();
- else if (node == NULL)
- return NULL;
- else
- {
- node->next->prev = node->prev;
- node->prev->next = node->next;
- node->next = node->prev = NULL;
- T node_data = node->data;
- delete node;
- this->counter--;
- return node_data;
- }
- }
- //Usuwa element po indeksie
- T* del(int number)
- {
- return this->del(this->get_Index(number));
- }
- //Zwraca wskaznik na dane z head
- T* ret_Head()
- {
- if (this->head)
- return this->head->data;
- else
- return NULL;
- }
- //Zwraca wskaznik na dane z tail
- T* ret_Tail()
- {
- if (this->head)
- return this->tail->dane;
- else
- return NULL;
- }
- //Zwraca wskaznik na list_node<T> po nr in indeksu
- List_Node<T>* get_Index(const int in)
- {
- if (in >= this->counter)
- {
- //cout << "Blad odczytu liczba poza zakresem\n";
- return NULL;
- }
- else
- {
- List_Node<T>* node;
- node = this->head;
- for (int i = 1; i <= in; i++)
- node = node->next;
- return node;
- }
- }
- //Zwraca ilosc elementow w liscie
- int get_Size()
- {
- return this->counter;
- }
- //Zwraca napis jednego elementu
- std::string to_string(List_Node<T>* node)
- {
- if (node == NULL)
- return "Blad odczytu \n";
- std::string str;
- str = node->data->to_string();
- return str;
- }
- //Zwraca napis jednego elementu po indeksie
- std::string to_string(const int number)
- {
- return this->to_string(this->get_Index(number));
- }
- //Zwraca cala liste do napisu
- std::string to_string()
- {
- if (this->head)
- {
- List_Node<T>* node;
- std::string kek;
- node = this->head;
- int i = 0;
- while (node)
- {
- i++;
- kek = kek + this->to_string(node) + " -> ";
- if (i > 5)
- break;
- node = node->next;
- }
- return kek;
- }
- else
- return "Lista pusta";
- }
- //Ustawia nowe dane na wskazanym miejscu
- void set(int index, T* dane)
- {
- List_Node<T>* node;
- node = this->get_Index(index);
- if (node == NULL)
- {
- std::cout << "Bledne dane wejsciowe \n\n";
- }
- else if (node->data != NULL)
- {
- node->data = dane;
- }
- else
- std::cout << "Bledne dane wejsciowe \n\n";
- }
- //Przeszukuje tablice i zwraca wskaznik na List_Node<T>
- T search(T number)
- {
- if (this->head)
- {
- List_Node<T>* node;
- node = this->head;
- T node_data = node->data;
- while (node)
- {
- //if (node_data == number)
- if (cmp(node_data,number))
- {
- //cout << "Znaleziono rekord\n\n";
- return node->data;
- }
- node = node->next;
- if (node)
- node_data = node->data;
- }
- //cout << "Nie znaleziono rekordu\n\n";
- return NULL;
- }
- else
- return NULL;
- }
- bool cmp(T data,T data1)
- {
- if (data1->name==data->name)
- return true;
- else
- return false;
- }
- T search(std::string number)
- {
- if (this->head)
- {
- List_Node<T>* node;
- node = this->head;
- T node_data = node->data;
- while (node)
- {
- if (*node_data == number)
- {
- //cout << "Znaleziono rekord\n\n";
- return node->data;
- }
- node = node->next;
- if (node)
- node_data = node->data;
- }
- //cout << "Nie znaleziono rekordu\n\n";
- return NULL;
- }
- else
- return NULL;
- }
- //Przeszukuje tablice i zwraca wskaznik na List_Node<T>
- //Wyswietla kilka wartosci i pozwala wybrac rekord
- List_Node<T>* searchd(T number)
- {
- if (this->head)
- {
- List_Node<T>* node;
- node = this->head;
- T node_data = node->data;
- while (node)
- {
- if (node_data == number)
- {
- //cout << "Znaleziono rekord\n\n";
- return node;
- }
- node = node->next;
- if (node)
- node_data = node->data;
- }
- //cout << "Nie znaleziono rekordu\n\n";
- return NULL;
- }
- else
- return NULL;
- }
- //Usuwa po liczbie
- T search_and_destroy(T number)
- {
- //cout << "Usuwanie po peselu " << number << endl;
- return del(searchd(number));
- }
- //Usuwa po stringu
- T search_and_destroy(std::string tx)
- {
- std::cout << "Usuwanie po nazwie" << std::endl;
- return del(search(tx));
- }
- };
- template<typename T>
- class Hasz
- {
- private:
- int Max_cap;
- int Act_cap;
- void rehash()
- {
- int newmax = Max_cap * 2;
- Lista<T>** newtab = new Lista<T> * [newmax];
- for (int i = 0; i < newmax; i++)
- {
- newtab[i] = new Lista<T>;
- }
- for (int i = 0; i < this->Act_cap; i++)
- {
- const int tmp = table[i]->counter;
- for (int j = 0; j < tmp; j++)
- {
- T tmp = table[i]->del_Front();
- std::string nazwa = tmp->name;
- int lenght = nazwa.length();
- int suma = 0;
- for (int i = 0; i < lenght; i++)
- {
- int x = lenght - i - 1;
- suma = suma + nazwa[i] * pow(31, x);
- }
- suma = suma % newmax;
- newtab[abs(suma)]->add_Front(tmp);
- }
- }
- for (int i = 0; i < Max_cap; i++)
- {
- table[i]->delete_(true);
- delete table[i];
- }
- delete[] table;
- Max_cap = newmax;
- table = newtab;
- }
- public:
- int getHash(std::string data)
- {
- int lenght = data.length();
- int suma = 0;
- for (int i = 0; i < lenght; i++)
- {
- int x = lenght - i - 1;
- suma = suma + data[i] * pow(31, x);
- }
- suma = suma % Max_cap;
- return abs(suma);
- }
- Lista<T>** table;
- Hasz()
- {
- Max_cap = 2;
- Act_cap = 0;
- table = new Lista<T> * [Max_cap];
- for (int i = 0; i < Max_cap; i++)
- {
- table[i] = new Lista<T>;
- }
- }
- void add(T data)
- {
- if (Act_cap >= (float)Max_cap * 0.75)
- this->rehash();
- std::string nazwa = data->name;
- int lenght = nazwa.length();
- int suma = 0;
- for (int i = 0; i < lenght; i++)
- {
- int x = lenght - i - 1;
- suma = suma + nazwa[i] * pow(31, x);
- }
- suma = suma % Max_cap;
- T tmp = table[abs(suma)]->search(data->name);
- if (tmp)
- {
- bool t;
- }
- table[abs(suma)]->add_Front(data);
- Act_cap++;
- }
- std::string to_string()
- {
- std::string str = "Ilosc elementow " + std::to_string(this->Act_cap) + " Max elementow " + std::to_string(this->Max_cap) + "\n";
- int j = 0;
- for (int i = 0; i < Max_cap; i++)
- {
- if (table[i]->counter == 0)
- {
- }
- else
- {
- str = str + table[i]->to_string() + "\n";
- j++;
- if (j >= 10)
- break;
- }
- }
- return str;
- }
- T findHash(T data)
- {
- int hasz = getHash(data->name);
- return table[hasz]->search(data);
- }
- bool deleteHash(T data)
- {
- int hasz = getHash(data->name);
- return (bool)table[hasz]->search_and_destroy(data);
- }
- void reset(bool t)
- {
- for (int i = 0; i < Max_cap; i++)
- {
- table[i]->delete_(t);
- delete table[i];
- }
- delete[] table;
- }
- std::string stats()
- {
- std::string str;
- int min = 7;
- int max = 0;
- int nulltables = 0;
- int sum = 0;
- for (int i = 0; i < Max_cap; i++)
- {
- if (max < table[i]->counter)
- max = table[i]->counter;
- if (table[i]->counter == 0)
- nulltables++;
- else
- {
- if (min > table[i]->counter)
- min = table[i]->counter;
- sum = sum + table[i]->counter;
- }
- }
- float avg = (float)sum / (Max_cap - nulltables);
- str = str + "Minimum = " + std::to_string(min);
- str = str + "\nMaximum = " + std::to_string(max);
- str = str + "\nSrednia = " + std::to_string(avg);
- str = str + "\nPuste listy = " + std::to_string(nulltables);
- return str;
- }
- };
- //int main()
- //{
- // Node<int> data("string", 6);
- // Node<int> data1("kusi", 1);
- // Node<int> data2("kek", 2);
- // Node<int> data3("XD", 69);
- // Node<int> nowy("nowy", 10);
- //
- // Hasz<Node<int>*>* hasz = new Hasz<Node<int>*>;
- //
- // hasz->add(&data);
- // std::cout << hasz->to_string() << std::endl << std::endl;
- // hasz->add(&data1);
- // std::cout << hasz->to_string() << std::endl << std::endl;
- // hasz->add(&data2);
- // std::cout << hasz->to_string() << std::endl << std::endl;
- // hasz->add(&data3);
- // std::cout << hasz->to_string() << std::endl << std::endl;
- // Node<int>*t = hasz->findHash(&data3);
- // *t = nowy;
- // if (t)
- // std::cout << t;
- //
- // std::cout << hasz->to_string() << std::endl << std::endl;
- // //hasz->delall();
- //}
- int main()
- {
- srand(time(NULL));
- const int MAX_ORDER = 6;
- for (int o = 5; o <= MAX_ORDER; o++)
- {
- Hasz<Node<int>*>* ht = new Hasz<Node<int>*>();
- const int n = pow(10, o);
- clock_t t1 = clock();
- for (int i = 0; i < n; i++)
- {
- Node<int>* data = new Node<int>();
- ht->add(data);
- }
- Node<int>* da = new Node<int>();
- Node<int>* dd = new Node<int>();
- da->data = 10;
- da->name = "aa";
- dd->data = 10;
- dd->name = "aa";
- ht->add(da);
- std::cout<<ht->getHash("aa");
- std::cout<<ht->findHash(dd);
- clock_t t2 = clock();
- double time1 = (t2 - t1) / (double)CLOCKS_PER_SEC;
- std::cout << "Przebieg: " << o << " Czas ogolny: " << time1 * 1000 << " milisekund. " << "Czas na element: " << (time1 / n) * 1000000 << " mikrosekund. " << std::endl;
- std::cout << ht->to_string() << std::endl;
- std::cout << ht->stats() << std::endl;
- const int m = pow(10, 4);
- int hits = 0;
- t1 = clock();
- for (int i = 0; i < m; i++)
- {
- Node<int>* dataf = new Node<int>();
- Node<int>* entry = ht->findHash(dataf); // wyszukiwanie wg losowego klucza
- if (entry)
- hits++;
- delete dataf;
- delete entry;
- }
- t2 = clock();
- double time2 = (t2 - t1) / (double)CLOCKS_PER_SEC;
- std::cout << "Szukanie: Trafien " << hits << " Czas ogolny: " << time2 * 1000 << " milisekund. " << "Czas na element: " << (time2 / n) * 1000000 << " mikrosekund. " << std::endl << std::endl;
- ht->reset(true);
- delete ht;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement