This commit is contained in:
Bohdan Kapliuk 2025-01-12 15:32:10 +02:00
parent d163fcaae8
commit db623c28ad
9 changed files with 362 additions and 79 deletions

View File

@ -9,5 +9,5 @@ train: main.o a_train.o
gcc main.o a_train.o -o train
clean:
rm *.o train
rm *.o train.exe

View File

@ -9,5 +9,5 @@ station: main.o a_station.o
gcc $(CFLAGS) main.o a_station.o -o station
clean:
rm *.o station
rm *.o station.exe

View File

@ -3,7 +3,6 @@
#include <stdio.h>
#include <string.h>
struct station* create_station(){
struct station* station = (struct station*)calloc(1,sizeof(struct station));
station->tracks = (struct car**)calloc(STATION_SIZE, sizeof(struct car*));
@ -11,7 +10,7 @@ struct station* create_station(){
return station;
}
void destroy_station(struct station* station){
void destroy_station(struct station* station) {
if (station == NULL) return;
for (int i = 0; i < station->track_count; i++) {
@ -26,7 +25,7 @@ void destroy_station(struct station* station){
free(station->tracks);
free(station);
}
}
int select_track(struct station* station, const char* target) {
unsigned long hash = 5381;

View File

@ -1,78 +1,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE 100
struct tree {
char* value;
struct tree* left;
struct tree* right;
};
struct tree* read_tree(int* counter) {
char buffer[SIZE];
memset(buffer, 0, SIZE);
char* r = fgets(buffer, SIZE, stdin);
if(r == NULL){
return 0;
}
if (buffer[0] == '\n') {
return 0;
}
struct tree* tree = calloc(1, sizeof(struct tree));
tree->value = malloc(strlen(buffer) + 1);
strcpy(tree->value, buffer);
if (buffer[0] == '*') {
(*counter)++;
return tree;
}
tree->left = read_tree(counter);
tree->right = read_tree(counter);
return tree;
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void printchar(char c) { write(1, &c, 1);
}
void destroy_tree(struct tree* tree) {
if (tree == NULL) return;
destroy_tree(tree->left);
destroy_tree(tree->right);
free(tree->value);
free(tree);
}
void print_tree(struct tree* tree) {
if (tree == NULL) return;
printf("%s", tree->value);
if (tree->value[0] == '*') {
printf("Koniec\n");
return;
}
getchar();
char r = getchar();
if (r == 'a') {
print_tree(tree->left);
} else if (r == 'n') {
print_tree(tree->right);
} else if (r == EOF) {
printf("Koniec vstupu\n");
}else {
printf("Nerozumiem\n");
exit(0);
}
}
int main() {
int counter = 0;
struct tree* root = read_tree(&counter);
if(root != 0){
printf("Expert z bufetu to vie.\n");
printf("Pozna %d druhov ovocia a zeleniny.\n", counter);
printf("Odpovedajte 'a' pre prvu moznost alebo 'n' pre druhu moznost.\n");
print_tree(root);
} else{
printf("Expert z bufetu to vie.\n");
printf("Chybna databaza\n");
}
destroy_tree(root);
return 0;
// Пишет символ 'c' в стандартный вывод
printchar('A'); // Bыbodum сuмbол do fork()
fork(); // Создается новый процесс
printchar('B');
return 0;
}

17
sk1/Makefile Normal file
View File

@ -0,0 +1,17 @@
CC = gcc
CFLAGS = -Wall -Wextra -std=c99
all: compressor
compressor: main.o compressor.o
$(CC) $(CFLAGS) -o compressor main.o compressor.o
main.o: main.c compressor.h
$(CC) $(CFLAGS) -c main.c
compressor.o: compressor.c compressor.h
$(CC) $(CFLAGS) -c compressor.c
clean:
rm -f *.o compressor

34
sk1/README.md Normal file
View File

@ -0,0 +1,34 @@
# Dokumentácia
## Zadanie
Vytvorte program na kompresiu a dekompresiu súborov pomocou dvoch rôznych algoritmov: RLE (Run Length Encoding) a LZ78. Program musí podporovať nasledujúce operácie:
- Kompresia pomocou RLE
- Dekompresia pomocou RLE
- Kompresia pomocou LZ78
- Dekompresia pomocou LZ78
## Stručný opis funkčnosti
Program `compressor` umožňuje kompresiu a dekompresiu súborov pomocou algoritmov RLE a LZ78. Program sa spúšťa z príkazového riadku s nasledujúcimi argumentmi:
- `-c infile outfile`: Kompresia pomocou algoritmu RLE
- `-d infile outfile`: Dekompresia pomocou algoritmu RLE
- `-c2 infile outfile`: Kompresia pomocou algoritmu LZ78
- `-d2 infile outfile`: Dekompresia pomocou algoritmu LZ78
- `-h`: Zobrazenie pomoci
## Stručný opis riešenia
Program je implementovaný v jazyku C a obsahuje nasledujúce súbory:
- `main.c`: Obsahuje hlavný program, ktorý spracováva argumenty príkazového riadku a volá príslušné funkcie na kompresiu a dekompresiu.
- `compressor.c`: Obsahuje implementáciu kompresných a dekompresných algoritmov RLE a LZ78.
- `compressor.h`: Hlavičkový súbor s deklaráciami funkcií.
- `Makefile`: Súbor na kompiláciu programu pomocou nástroja `make`.
Algoritmus RLE komprimuje súbor tak, že nahradí opakujúce sa znaky dvojicou (znak, počet opakovaní). Algoritmus LZ78 komprimuje súbor tak, že nahradí opakujúce sa sekvencie znakov dvojicou (index, znak), kde index odkazuje na predchádzajúcu sekvenciu v slovníku.
## Podmienky za ktorých funguje
Program bol testovaný na systéme Windows s kompilátorom GCC. Na kompiláciu programu použite príkaz `make` v príkazovom riadku. Program vyžaduje, aby vstupné súbory existovali a boli čitateľné. Výstupné súbory budú vytvorené alebo prepísané.
## Zoznam použitých zdrojov
- Dokumentácia k jazyku C
- Wikipedia: [Run Length Encoding](https://en.wikipedia.org/wiki/Run-length_encoding)
- Wikipedia: [LZ78](https://en.wikipedia.org/wiki/LZ78)
- [Stránka predmetu](https://student.kemt.fei.tuke.sk/usaa/home)

223
sk1/compressor.c Normal file
View File

@ -0,0 +1,223 @@
#include "compressor.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_DICT_SIZE 4096
int read_file(const char* filename, unsigned char** data, size_t* size) {
FILE* file = fopen(filename, "rb");
if (!file) return -1;
fseek(file, 0, SEEK_END);
*size = ftell(file);
fseek(file, 0, SEEK_SET);
*data = malloc(*size);
if (!*data) {
fclose(file);
return -1;
}
fread(*data, 1, *size, file);
fclose(file);
return 0;
}
int write_file(const char* filename, const unsigned char* data, size_t size) {
FILE* file = fopen(filename, "wb");
if (!file) return -1;
fwrite(data, 1, size, file);
fclose(file);
return 0;
}
//RLE
int compress_1(const char* input_file_name, const char* output_file_name) {
size_t size;
unsigned char* data;
if (read_file(input_file_name, &data, &size) != 0) return -1;
FILE* output = fopen(output_file_name, "w");
if (!output) {
free(data);
return -1;
}
for (size_t i = 0; i < size;) {
unsigned char byte = data[i];
size_t count = 1;
while (i + count < size && data[i + count] == byte && count < 255) {
count++;
}
fprintf(output, "%c%d", byte, (int)count);
i += count;
}
fclose(output);
free(data);
return 0;
}
unsigned char* decompress_1_buffer(const unsigned char* data, size_t size, size_t* out_size) {
unsigned char* decompressed = malloc(size * 255);
if (!decompressed) return NULL;
size_t write_idx = 0;
for (size_t i = 0; i < size;) {
unsigned char byte = data[i++];
size_t count = 0;
while (i < size && isdigit(data[i])) {
count = count * 10 + (data[i++] - '0');
}
for (size_t j = 0; j < count; j++) {
if (write_idx >= size * 255) {
size_t new_size = write_idx * 2;
unsigned char* new_buffer = realloc(decompressed, new_size);
if (!new_buffer) {
free(decompressed);
return NULL;
}
decompressed = new_buffer;
}
decompressed[write_idx++] = byte;
}
}
*out_size = write_idx;
return decompressed;
}
int decompress_1(const char* input_file_name, const char* output_file_name) {
size_t size;
unsigned char* data;
if (read_file(input_file_name, &data, &size) != 0) return -1;
size_t out_size;
unsigned char* decompressed = decompress_1_buffer(data, size, &out_size);
if (!decompressed) {
free(data);
return -1;
}
int result = write_file(output_file_name, decompressed, out_size);
free(data);
free(decompressed);
return result == 0 ? (int)out_size : -1;
}
// LZ78
int compress_2(const char* input_file_name, const char* output_file_name) {
unsigned char* data;
size_t size;
if (read_file(input_file_name, &data, &size) != 0) {
return -1;
}
FILE* output = fopen(output_file_name, "w");
if (!output) {
free(data);
return -1;
}
unsigned char* dictionary[MAX_DICT_SIZE] = { NULL };
size_t dict_size = 0;
size_t current_index = 0;
while (current_index < size) {
size_t match_index = 0;
size_t match_length = 0;
for (size_t i = 0; i < dict_size; i++) {
size_t len = 0;
while (data[current_index + len] != '\0' &&
dictionary[i][len] != '\0' &&
data[current_index + len] == dictionary[i][len]) {
len++;
}
if (len > match_length) {
match_length = len;
match_index = i + 1;
}
}
if (current_index + match_length < size) {
fprintf(output, "%zu%c", match_index, data[current_index + match_length]);
}
if (dict_size < MAX_DICT_SIZE) {
dictionary[dict_size] = malloc(match_length + 2);
if (!dictionary[dict_size]) {
fclose(output);
free(data);
for (size_t i = 0; i < dict_size; i++) {
free(dictionary[i]);
}
return -1;
}
if (match_length > 0) {
memcpy(dictionary[dict_size], &data[current_index], match_length);
}
dictionary[dict_size][match_length] = data[current_index + match_length];
dictionary[dict_size][match_length + 1] = '\0';
dict_size++;
}
current_index += match_length + 1;
}
fclose(output);
free(data);
for (size_t i = 0; i < dict_size; i++) {
free(dictionary[i]);
}
return 0;
}
int decompress_2(const char* input_file_name, const char* output_file_name) {
unsigned char* data;
size_t size;
if (read_file(input_file_name, &data, &size) != 0) {
return -1;
}
FILE* output = fopen(output_file_name, "w");
if (!output) {
free(data);
return -1;
}
unsigned char* dictionary[MAX_DICT_SIZE] = { NULL };
size_t dict_size = 0;
size_t current_index = 0;
while (current_index < size) {
unsigned short index = 0;
unsigned char ch = '\0';
while (current_index < size && isdigit(data[current_index])) {
index = index * 10 + (data[current_index] - '0');
current_index++;
}
if (current_index < size) {
ch = data[current_index++];
}
if (index == 0) {
fputc(ch, output);
} else {
fwrite(dictionary[index - 1], 1, strlen((char*)dictionary[index - 1]), output);
fputc(ch, output);
}
if (dict_size < MAX_DICT_SIZE) {
size_t length = (index > 0) ? strlen((char*)dictionary[index - 1]) : 0;
dictionary[dict_size] = malloc(length + 2);
if (!dictionary[dict_size]) {
fclose(output);
free(data);
for (size_t i = 0; i < dict_size; i++) {
free(dictionary[i]);
}
return -1;
}
if (index > 0) {
memcpy(dictionary[dict_size], dictionary[index - 1], length);
}
dictionary[dict_size][length] = ch;
dictionary[dict_size][length + 1] = '\0';
dict_size++;
}
}
fclose(output);
free(data);
for (size_t i = 0; i < dict_size; i++) {
free(dictionary[i]);
}
return 0;
}

9
sk1/compressor.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef COMPRESSOR_H
#define COMPRESSOR_H
int compress_1(const char* input_file_name, const char* output_file_name);
int decompress_1(const char* input_file_name, const char* output_file_name);
int compress_2(const char* input_file_name, const char* output_file_name);
int decompress_2(const char* input_file_name, const char* output_file_name);
#endif

66
sk1/main.c Normal file
View File

@ -0,0 +1,66 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "compressor.h"
void print_help() {
printf("Použitie:\n");
printf(" ./compressor -c infile outfile # Kompresia pomocou algoritmu RLE\n");
printf(" ./compressor -d infile outfile # Dekompresia pomocou algoritmu RLE\n");
printf(" ./compressor -c2 infile outfile # Kompresia pomocou algoritmu LZ78\n");
printf(" ./compressor -d2 infile outfile # Dekompresia pomocou algoritmu LZ78\n");
printf(" ./compressor -h # Zobrazit pomoc\n");
}
int main(int argc, char* argv[]) {
if (argc < 2) {
fprintf(stderr, "Chyba: Chybaju argumenty. Pouzite -h pre zobrazenie pomoci.\n");
return 1;
}
if (strcmp(argv[1], "-h") == 0) {
print_help();
return 0;
}
if ((strcmp(argv[1], "-c") == 0 || strcmp(argv[1], "-d") == 0 ||
strcmp(argv[1], "-c2") == 0 || strcmp(argv[1], "-d2") == 0) && argc != 4) {
fprintf(stderr, "Chyba: Nespravny pocet argumentov. Pouzite -h pre zobrazenie pomoci.\n");
return 1;
}
const char* input_file = argv[2];
const char* output_file = argv[3];
int result = 0;
if (strcmp(argv[1], "-c") == 0) {
result = compress_1(input_file, output_file);
if (result < 0) {
fprintf(stderr, "Chyba: Kompresia zlyhala.\n");
return 1;
}
} else if (strcmp(argv[1], "-d") == 0) {
result = decompress_1(input_file, output_file);
if (result < 0) {
fprintf(stderr, "Chyba: Dekompresia zlyhala.\n");
return 1;
}
} else if (strcmp(argv[1], "-c2") == 0) {
result = compress_2(input_file, output_file);
if (result < 0) {
fprintf(stderr, "Chyba: Kompresia zlyhala.\n");
return 1;
}
} else if (strcmp(argv[1], "-d2") == 0) {
result = decompress_2(input_file, output_file);
if (result < 0) {
fprintf(stderr, "Chyba: Dekompresia zlyhala.\n");
return 1;
}
} else {
fprintf(stderr, "Chyba: Neznamy argument. Použite -h pre zobrazenie pomoci.\n");
return 1;
}
return 0;
}