160 lines
4.9 KiB
C++
160 lines
4.9 KiB
C++
#include <iostream>
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
#include <random>
|
|
#include <iomanip>
|
|
|
|
//#include <limits>
|
|
//#include <algorithm>
|
|
//#include <string>
|
|
//#include <iomanip>
|
|
//#include <fstream>
|
|
//#include <clocale>
|
|
|
|
#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;
|
|
}
|
|
|
|
|
|
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<double, std::micro> 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}){
|
|
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<double, std::micro> czas = stop - start;
|
|
std::cerr << "Uplynelo: " << czas.count() << " us\n";
|
|
std::cerr << "Ilość wywołań funkcji wstawiającej: " << g_counter << "\n";
|
|
}
|
|
|
|
//...
|
|
|
|
return 0;
|
|
}
|