diff --git a/du5/Makefile b/du5/Makefile new file mode 100644 index 0000000..8cec7f4 --- /dev/null +++ b/du5/Makefile @@ -0,0 +1,13 @@ +CFLAGS= -std=c99 -g -Wall -Werror + +all: station + +%.o: %.c + gcc -c -o $@ $< $(CFLAGS) + +station: main.o a_station.o + gcc $(CFLAGS) main.o a_station.o -o station + +clean: + rm *.o station + diff --git a/du5/a_station.c b/du5/a_station.c new file mode 100644 index 0000000..d176154 --- /dev/null +++ b/du5/a_station.c @@ -0,0 +1,113 @@ +#include "a_station.h" +#include +#include +#include + +// ------------------------ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ------------------------ + +// Простая хеш-функция: превращает текст в индекс +static int hash_to_index(struct station* station, const char* target) { + unsigned long hash = 0; + for (int i = 0; target[i] != '\0'; i++) + hash = hash * 31 + target[i]; // простая формула + return (station && station->track_count > 0) + ? (int)(hash % station->track_count) + : 0; +} + +// Создаёт новый элемент car и вставляет в начало списка +static void insert_new_car(struct car** head, const char* target, int capacity) { + struct car* newcar = malloc(sizeof(struct car)); + if (!newcar) return; // проверка памяти + strncpy(newcar->value, target, TARGET_SIZE - 1); + newcar->value[TARGET_SIZE - 1] = '\0'; + newcar->capacity = capacity; + newcar->next = *head; + *head = newcar; +} + +// ------------------------ ОСНОВНЫЕ ФУНКЦИИ ------------------------ + +// Создание пустой станции (хеш-таблицы) +struct station* create_station() { + struct station* s = calloc(1, sizeof(struct station)); + s->tracks = calloc(STATION_SIZE, sizeof(struct car*)); + s->track_count = STATION_SIZE; + return s; +} + +// Удаление станции и всех элементов +void destroy_station(struct station* s) { + if (!s) return; + for (int i = 0; i < s->track_count; i++) { + struct car* cur = s->tracks[i]; + while (cur) { + struct car* next = cur->next; + free(cur); + cur = next; + } + } + free(s->tracks); + free(s); +} + +// Выбор индекса колеи по названию станции +int select_track(struct station* s, const char* target) { + return hash_to_index(s, target); +} + +// Добавление или обновление записи +void add_target_capacity(struct station* s, const char* target, int capacity) { + if (!s || !target) return; + + int index = select_track(s, target); + struct car* cur = s->tracks[index]; + + // ищем существующую станцию + while (cur) { + if (strcmp(cur->value, target) == 0) { + cur->capacity += capacity; // нашли → увеличиваем + return; + } + cur = cur->next; + } + + // не нашли → создаём новую запись + insert_new_car(&s->tracks[index], target, capacity); +} + +// Получение количества пассажиров для станции +int get_target_capacity(struct station* s, const char* target) { + if (!s || !target) return 0; + + int index = select_track(s, target); + struct car* cur = s->tracks[index]; + + while (cur) { + if (strcmp(cur->value, target) == 0) + return cur->capacity; + cur = cur->next; + } + + return 0; +} + +// Подсчёт количества всех разных станций +int count_targets(struct station* s) { + if (!s) return 0; + int count = 0; + for (int i = 0; i < s->track_count; i++) + for (struct car* cur = s->tracks[i]; cur; cur = cur->next) + count++; + return count; +} + +// Подсчёт общей вместимости всех станций +int count_capacity(struct station* s) { + if (!s) return 0; + int total = 0; + for (int i = 0; i < s->track_count; i++) + for (struct car* cur = s->tracks[i]; cur; cur = cur->next) + total += cur->capacity; + return total; +} diff --git a/du5/a_station.h b/du5/a_station.h new file mode 100644 index 0000000..ce8c733 --- /dev/null +++ b/du5/a_station.h @@ -0,0 +1,91 @@ +#ifndef STATION_H +#define STATION_H +// Pocet trati k dispozicii +#define STATION_SIZE 10 +// Maximalny pocet znakov pre ulozenie nazvu cielovej stanice +#define TARGET_SIZE 36 + +/** + * Jeden zaznam o kapacite do cielovej stanice + */ +struct car { + // Cielova stanica / nazov + char value[TARGET_SIZE]; + // Pocet cestujuchich + int capacity; + // Smernik na dalsi zaznam + struct car* next; +}; + +/** + * Cela databaza zaznamov + */ +struct station { + // Dynamicke pole smernikov na zaznamy + // jeden zaznam ma typ struct car* + struct car** tracks; + // Velkost pola tracks + int track_count; +}; + + +/** + * Vytvori prazdnu stanicu. + * Alokuje pole smernikov tracks na pociatocnu kapacitu STATION_SIZE + * nastavi velkost capacity na STATION_SIZE + * @return smernik na prazdnu stanicu + */ +struct station* create_station(); + +/** + * Uvolni pamat + * @param smernik na databazu + */ +void destroy_station(struct station* station); + +/** + * Vyberie poziciu v poli station->tracks pre ulozenie zaznamu target + * + * Proces vyberu by mal splnat kriteria pre hash funkciu: + * - rovnaky retazec by mal vzdy mat rovnaky vysledok + * - pre rozne retazce by mali byt vysledky co najviac rozne + * + * @param smernik na databazu + * @param nazov cielovej stanice + * @return cislo v intervale 0 az N-1, kde N je station->track_count + */ +int select_track(struct station* station, const char* target); + +/** + * Zvysi zaznam o pocte cestujucich do danej cielovej stanice. + * + * Najprv sa vyberie cielova trat pomocou select_track(). Ak zaznam neexistuje, + * vytvori sa novy. Ak zaznam na danej trati (spojkovom zozname) existuje, cislo sa pripocita. + * V databaze nesmu byt dva zaznamy s rovnakou cielovou stanicou. + * + * @param smernik na databazu + * @param nazov cielovej stanice + */ +void add_target_capacity(struct station* station,const char* target, int capacity); + +/** + * Ziska zaznam o cielovej stanici. + * @param smernik na databazu + * @param nazov cielovej stanice + * + * @return kapacitu do cielovej stanice. Ak sa zaznam nenachedza, vrati nula. + */ +int get_target_capacity(struct station* station,const char* target); + +/** + * Spocita pocet cielovych stanic + * @param smernik na databazu + */ +int count_targets(struct station* station); + +/** + * Spocita kapacitu vo vsetkych zaznamoch + * @param smernik na databazu + */ +int count_capacity(struct station* station); +#endif diff --git a/du5/main.c b/du5/main.c new file mode 100644 index 0000000..a909625 --- /dev/null +++ b/du5/main.c @@ -0,0 +1,41 @@ +#include "a_station.h" +#include +#include +#include + +void print_station(struct station* station){ + // Vypise celu stanicu + printf("station>>>\n"); + // Prechadza vsetky trate + for (int i = 0 ; i< station->track_count; i++){ + struct car* start = station->tracks[i]; + struct car* this = start; + // Prechadza vsetky vozne + while(this != NULL){ + printf("%s %d -> ",this->value,this->capacity); + this=this->next; + } + printf("NULL\n"); + } + printf("<<