Files
AiSD/projekt 1/main.cpp
2023-03-15 14:29:25 +01:00

201 lines
6.1 KiB
C++

#include <iostream>
#include <chrono>
#include <random>
#include <limits>
#include <algorithm>
#include <string>
#include <iomanip>
#include <fstream>
#include <clocale>
using std::swap;
int losowa_liczba(int min, int max)
{
static std::default_random_engine gen(std::random_device{}());
static std::uniform_int_distribution<int> dist;
return dist(gen, std::uniform_int_distribution<int>::param_type{ min, max });
}
void wypelnij(int* tablica, int rozmiar, int min = 0, int max = std::numeric_limits<int>::max())
{
for (int i = 0; i < rozmiar; ++i)
tablica[i] = losowa_liczba(min, max);
}
bool jest_posortowane(int* tablica, int rozmiar)
{
return std::is_sorted(tablica, tablica + rozmiar);
}
double mierz_czas(int* tablica, int rozmiar, void(*funkcja_sortujaca)(int*, int))
{
auto start = std::chrono::high_resolution_clock::now();
funkcja_sortujaca(tablica, rozmiar);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = end - start;
return duration.count();
}
/*
parametry:
- funkcja_sortujaca - wskanik na funkcjącą sortowanie, musi przyjmować dwa parametry: adres początku tablicy (int*) oraz jej rozmiar (int)
- nazwa - nazwa testowanej funkcji, tylko w celach wypisania
- output - strumien do ktorego beda zapisane wyniki, domyslnie std::cerr, przy ostatnim uruchomieniu warto nadpisac otwartym strumieniem plikowym, aby sobie zebrac wyniki do pliku
- dodatkowe_miejsce - liczba dodatkowych elementow tablicy zaalokowanych PRZED poczatkiem tablicy, przykladowo gdy =1, pierwszym indeksem tablicy jest -1, ale dane rozpoczynaja sie od indeksu 0, moze sie przydac do sortowania przez wstawianie z wartownikiem
*/
void eksperyment(void(*funkcja_sortujaca)(int*, int), const std::string& nazwa, std::ostream& output = std::cerr, int dodatkowe_miejsce = 0)
{
//ustawienia
const double limit_czasu = 25.0; //sekund
const int powtorzen = 3;
const int rozmiar_poczatkowy = 1 << 10;
/////////////////////////////////////////
const int szerokosc = 100;
int gwiazdek = szerokosc - nazwa.length() - 2;
if (gwiazdek < 0)
gwiazdek = 0;
int i = 0;
output << " ";
for (; i < gwiazdek / 2; ++i)
output << '*';
output << " " << nazwa << " ";
for (; i < gwiazdek; ++i)
output << '*';
output << "\n\n";
output.flush();
output << std::setw(9) << "N";
output << std::setw(1) << "";
for (int nr = 0; nr < powtorzen; ++nr)
output << std::setw(9) << nr + 1 << " ";
output << std::setw(12) << "średnia" << " ";
output << "\n";
for (int rozmiar = rozmiar_poczatkowy; ; rozmiar *= 2)
{
output << std::setw(9) << rozmiar << ": ";
output.flush();
int* pamiec = new int[dodatkowe_miejsce + rozmiar];
int* tablica = pamiec + dodatkowe_miejsce;
double czas = 0.0;
int* pattern = new int[rozmiar];
for (int nr = 0; nr < powtorzen; ++nr)
{
wypelnij(tablica, rozmiar);
for (int i = 0; i < rozmiar; ++i)
pattern[i] = tablica[i];
std::sort(pattern, pattern + rozmiar);
double c = mierz_czas(tablica, rozmiar, funkcja_sortujaca);
if (!jest_posortowane(tablica, rozmiar))
{
output << "Tablica nieposortowana!!\n";
if (&output != &std::cerr)
std::cerr << "Tablica nieposortowana!!\n";
return;
}
if (!std::equal(pattern, pattern + rozmiar, tablica, tablica + rozmiar))
{
output << "Tablica zawiera inne wartosci niz powinna!!\n";
if (&output != &std::cerr)
std::cerr << "Tablica zawiera inne wartosci niz powinna!!\n";
return;
}
czas += c;
output.precision(6);
output << std::fixed << c << " ";
output.flush();
}
czas /= powtorzen;
output << std::setw(12) << std::fixed << czas << "\n";
output.flush();
delete[] pamiec;
delete[] pattern;
if (czas > limit_czasu)
break;
}
output << "\n";
output.flush();
}
void sortowanie_wybieranie(int* tablica, int rozmiar){
for (int i = 0; i < rozmiar - 1; i++) {
int k = i;
int x = tablica[i];
for (int ii = i+1; ii < rozmiar; ii++) {
if (tablica[ii] < x) {
k = ii;
x = tablica[ii];
}
}
tablica[k]=tablica[i];
tablica[i]=x;
}
}
void sortowanie_wstawianie(int* tablica, int rozmiar){
for (int i = 1; i < rozmiar; i++) {
int x = tablica[i];
int ii = i - 1;
while ((ii > -1) && (x < tablica[ii])) {
tablica[ii+1] = tablica[ii];
ii=ii-1;
}
tablica[ii+1] = x;
}
}
void sortowanie_babelkowe(int* tablica, int rozmiar)
{
for(int i = 0; i < rozmiar; i++)
{
for (int ii = 1; ii < rozmiar; ii++) {
if (tablica[ii-1] > tablica[ii]) {
swap(tablica[ii-1], tablica[ii]);
}
}
}
}
void ulepszone_sortowanie_babelkowe(int* tablica, int rozmiar)
{
bool wejscie_do_ifa=false;
for(int i = 0; i < rozmiar; i++)
{
for (int ii = 1; ii < rozmiar-i; ii++) {
if (tablica[ii-1] > tablica[ii]) {
wejscie_do_ifa = true;
swap(tablica[ii-1], tablica[ii]);
}
}
if (wejscie_do_ifa==false) {break;}
}
}
int main()
{
setlocale(LC_ALL, "");
std::ofstream wyniki("wyniki.txt");
//std::ostream& output = wyniki;//std::cerr; // Wypisanie do pliku (zamiast na ekran)
std::ostream& output = std::cerr; // Wypisanie na ekran
eksperyment(ulepszone_sortowanie_babelkowe, "Ulepszone sortowanie bąbelkowe", output);
eksperyment(sortowanie_babelkowe, "Sortowanie bąbelkowe", output);
eksperyment(sortowanie_wstawianie, "Sortowanie przez proste wstawianie", output);
eksperyment(sortowanie_wybieranie, "Sortowanie przez proste wybieranie", output);
return 0;
}