#include "a_station.h" #include #include #include // funkcia pre vytvorenie stanice struct station* create_station(){ // allokujeme dynamicke v pamati (na heape) pomocou calloc; vsetky byty su inticializovane na 0 // tak tiez, allokujeme 1 krat struct station* station = (struct station*)calloc(1,sizeof(struct station)); // double pointer: potrebujeme menit hodnotu; to je pointer na adresu ineho pointeru, a tot - na hodnotu. // Defaultne referencia je na prvy pointer pol'a. Allokacia 10 krat (makros) station->tracks = (struct car**)calloc(STATION_SIZE, sizeof(struct car*)); station->track_count = STATION_SIZE; return station; } /// funkcia pre uvolnenie pamati void destroy_station(struct station* station){ /// prechadzanie a uvolnenie jednotlyvich linked listov a ich prvkov for(int i = 0; itrack_count; i++){ struct car* tmp = station->tracks[i]; while(tmp){ struct car* toFree = tmp; tmp = tmp->next; free(toFree); } } // Mozeme uvolnit' array jednoducho, pretoze allokovali sme ho ako jeden 'kus' free(station->tracks); // uvolnenie stanice free(station); } // Heshovacia funckica int select_track(struct station* station, const char* target){ /// Pouzivame unsigned int pretoze cislo nesmie byt' zapornym unsigned int hash = 0; ///iteracia po prvkoch kluca for (int i = 0; i < strlen(target); i++) /// Operator << je bitovy posun vl'avo. To iste ako vynasobit' nieco na 2^n. ///Napriklad <<6 je to iste ako * 2^6 { hash += target[i] + (hash<<6) + (hash<<16) - hash; } /// Budeme mat' obrovske cislo na e vysledku, aj tak musime pouzit' mod velkos'ti pol'a. /// Index musi byt' v intervale od 0 do n-1. hash = hash %station->track_count; return hash; } // Funkica pre vytvorenie noveho nodu v poli alebo zvacsenie capacity void add_target_capacity(struct station* station,const char* target, int capacity){ // Dostaneme index int res = select_track(station, target); /// Pomocny pointer pre predchadzajucy struct car* previous = NULL; // adresa hlavy pre iteraciu. Prvok pod indexom. Vlasne, potrebuejeme vziat' adresu nodu, co robime. struct car** ptr = &station->tracks[res]; //Berieme hodnotu - adresu pointeru pre iteraciu. struct car* head = *ptr; /// Prechadzame po linked listu while(head){ //Ak destinacia nodu a hl'adane su rovnake, tak zvacsime capacitu nodu a prerusime program. if(strcmp(head->value, target) == 0){ head->capacity += capacity; return; } /// Prechadzame linked list previous = head; head = head->next; } // Ak sme vysli z cyklusu, to znamena ze polozka z prislusnym kl'ucom neexistuje a potrebuejeme vytvorit' nod. //Vytvorame nod a prerdaime hodnoty struct car* next = (struct car*)calloc(1, sizeof(struct car)); strcpy(next->value, target); next->capacity = capacity; //Ak posledny nod nie je NULL, ho nasledujucy bude vytvoreny if(previous){ previous->next = next; } //Inak, zoznam prazdny a pointer pojde na adresu v pamati vytvoreneho else{ *ptr = next; } } /// Funkcia na dostanie capacity(hodnoty) kl'uca int get_target_capacity(struct station* station,const char* target){ /// Index res podl'a kl'uca int res = select_track(station, target); /// Pointer na jednotlivy linked list struct car** ptr = &station->tracks[res]; /// Berieme prvy nod v nom pre prechadzanie, cize berieme hodnotu double pointeru; struct car* head = *ptr; /// pokial' nie jie NULL while (head) // Ak najdeme v linked liste s prislusnym indexom nod z kl'com hl'adanym, tak vratime hodnotu tho nodu (capacitu) {if(strcmp(head->value, target) == 0){ return head->capacity; } /// prechadzanie head = head->next; } //Inak - nenajsli a vratime 0 return 0; } // Funkcia pre pocet vsetkych destinacii int count_targets(struct station* station){ /// Ak je stanica NULL alebo pole NULL, vratime 0 /// || - logicky operator OR v C if(station == NULL || station->tracks == NULL){ return 0; } int total = 0; /// Iteracia po linked listoch pol'a for(int i = 0; itrack_count; i++){ /// Pomocny pointer pre prechadzanie po jednotliyvych polozkach linked lista struct car* ptr = station->tracks[i]; /// Incrementujeme pocet ak nie je to NULL, respektive je nejaka destinacia a prechadzame d'alej while(ptr){ total++; ptr = ptr->next; } } /// Vratime pocet return total; } /// Funkcia pre spocitanie vsetkych capacit (hodnot) int count_capacity(struct station* station){ // Ak stanica je NULL alebo pole je NULL - vratime 0 if(station == NULL || station->tracks == NULL){ return 0; } int total = 0; /// Iteracia po linked listoch v pole for(int i = 0; itrack_count; i++){ /// Pomocny pointer pre prechadzanie struct car* ptr = station->tracks[i]; while(ptr){ /// Pripocitame capacitu nodu a pojdeme d'alej total += ptr->capacity; ptr = ptr->next; } } /// Vratime sucet return total; }