#include #include #include #include #include //#include //#include //#include //#include //#include //#include #define EMPTY -1 // puste miejsce w tablicy mieszajacej #define REMOVED -2 // puste miejsce tablicy mieszajacej z ktorego usuniety zostal jakis element long long int g_counter {0}; //Zad. 1 Wstawianie do tablicy mieszajacej (adresowanie liniowe) /** Funkcja mieszająca wykorzystująca adresowanie liniowe @param x element dla którego obliczamy wartość funkcji mieszającej @param m rozmiar tablicy do której wstawiamy (parametr funki mieszajacej) @param i która to próba wstawienia/które obliczenie funkcji mieszającej (parametr funki mieszajacej) @return wartość f. mieszającej, pod ten indeks próbujemy wstawić potem x */ int h(int x, int m, int i){ g_counter++; if (i==0) { return x % m; } else { return (x % m + i) % m; } }; /** Funkcja wstawiajaca jeden element x do tablicy mieszajacej tab o rozmiarze m @param A tablica mieszajaca @param m rozmiar tablicy mieszajacej @param x element wstawiany do tablicy @return true, jesli element zostal wstawiony; false, jesli nie udalo sie wstawic elementu (brak miejsca w tablicy) */ bool hash_al_wstaw(int * A, int m, int x) { // Zaimplementuj //... for (int i = 0; i < m-1; i++) { int k = h(x, m, i); if (A[k] == EMPTY || A[k] == REMOVED){ A[k]=x; return true; } } return false; } bool hash_al_szukaj(int x, int m, int * A){ for (int i = 0; i < m; i++) { int k = h(x, i, m); if (A[k] == x){ return true;} if (A[k] == EMPTY){ return false;} } return false; } int main() { std::cout << "Zadanie 1 i 2:\n"; // Zad. 2 (rozgrzewka + test) const int m1 = 8; //rozmiar tablicy mieszajacej int t[m1]; //tablica mieszajaca // Wyczyszczenie tablicy mieszajacej t (Wypelnienie pustymi miejscami) for (int i = 0; i < m1; i++) { t[i] = EMPTY; } // Wstawianie elementów do tablicy mieszajacej t (uzyć funkcji hash_al_wstaw) for(int x : {8,6,18,11,3,32,19,27}) { hash_al_wstaw(t, m1, x); } // ... // Wyswietlenie tablicy mieszajacej t o rozmiarze m1 std::cout << std::setw(7) << "indeks:"; for (int i = 0; i < m1; i++) { std::cout << std::setw(11) << i; } std::cout << std::endl; std::cout << std::setw(8) << "|"; for (int i = 0; i < m1; i++) { std::cout << std::setw(10) << t[i] << "|" ; } std::cout << std::endl; // Zad. 3 Pomiary std::cout << "\nZadanie 3:\n"; // a) Tablica z danymi // Tworzenie tablicy dane z danymi do wstawinia do tablicy mieszajacej int rozm_dane = 20000000; //liczba elementow w tablicy dane int* dane = new int[rozm_dane]; //wypelnienie tablicy dane kolejnymi liczbami od 0 do rozm_dane-1 for (int i = 0;i < rozm_dane;i++) { dane[i] = i; } std::random_device rd; std::mt19937 g(rd()); std::shuffle(dane, dane + rozm_dane, g); //losowa permutacja elementow w tablicy dane (wymieszanie tablicy) // b) Tablica mieszajaca // Utworz pusta tablice mieszajaca tab o rozmiarze m = 2097152 (2 do potegi 21) const int m = 2097152; int * tab = new int[m]; for (int i = 0; i < m ; i++) { tab[i] = EMPTY; } // ... // c) Wstaw 10000 elemetow z tablicy dane do pustej tablicy mieszajacej tab (zapelnienie 0%). Na tej podstawie zmierz sredni czas wstawiania elementu oraz srednią liczbe wywolan funkcji mieszajacej przy wstawianiu elementu do pustej tablicy. std::cout << "Pomiary:\n"; g_counter = 0; // Mierzenie czasu, przyklad: auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < 10000; i++) { hash_al_wstaw(tab, m, dane[i]); } //tutaj mierzona operacja auto stop = std::chrono::high_resolution_clock::now(); std::chrono::duration czas = stop - start; std::cerr << "Uplynelo: " << czas.count() << " us\n"; std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n"; // d) Zmierz sredni czas wstawiania elementu oraz srednią liczbe wywolan funkcji mieszajacej przy wstawianiu elementu do tablicy wypelnionej w 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% (dla próbki: 10000 elementów). //UWAGA! Do tablicy mieszajacej nie wstawiac elementow, ktore juz w niej sa. for(double range : {0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9}){ for (int i = 0; i < m ; i++) { tab[i] = EMPTY; } g_counter = 0; for (int i = 0; i < range*m; i++) { hash_al_wstaw(tab, m, dane[i]); } g_counter = 0; // Mierzenie czasu, przyklad: std::cerr << "Pomiar dla " << range*100 << "%\n"; auto start = std::chrono::high_resolution_clock::now(); for (int i = range*m; i < (range*m)+10000; i++) { hash_al_wstaw(tab, m, dane[i]); } auto stop = std::chrono::high_resolution_clock::now(); std::chrono::duration czas = stop - start; std::cerr << "Uplynelo: " << czas.count() << " us\n"; std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n"; } //... return 0; }