114 lines
3.6 KiB
C
114 lines
3.6 KiB
C
#include "a_station.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
// ------------------------ ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ------------------------
|
|
|
|
// Простая хеш-функция: превращает текст в индекс
|
|
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;
|
|
}
|