Strukture podataka

Autor zadatka: Relja Mihić <relja.mihic@uns.ac.rs>

Ime ulazne datoteke učitati argumentom komandne linije. Ulazna datoteka sadrži podatke strukturama podataka:

  • naziv (jedna reč, do 40 karaktera)

  • memorija_elementa (ceo broj, u bajtima)

  • prosecno_trajanje_pretrage (jedna reč, do 3 karaktera)

Učitati podatke u jednostruko spregnutu listu dodavanjem novih elemenata na kraj liste. U izlaznu datoteku pod nazivom memorija.txt ispisati imena i ukupno memorije potrebno za čuvanje broja elemenata učitanog preko argumenta komandne linije. Memoriju izraziti u kilobajtima (kB), ako važi da je 1kB = 1024bajta. Za uneti broj elemenata, ispisati na standardnom izlazu za svaku strukturu vreme prosečne pretrage, ako:

  • 1 - je potrebna jedna operacija, otpr. 5 nanosekundi

  • log - je potrebno 5 * log(n) nanosekundi

  • n - je potrebno 5 * n nanosekundi

U slučaju uspešnog izvršavanja programa, izaći sa status kodom 0 (EXIT_SUCCESS). Ukoliko program ne može da se izvrši do kraja usled sledećih nedostataka, izaći iz programa sa sledećim status kodovima:

  • U slučaju nedovoljnog ili suvišnog broj argumenata komandne linije, izaći iz programa status kodom 1 (EXIT_FAILURE)

  • Ako nije uspešno otvorena ulazna datoteka, izaći iz programa sa status kodom 2

  • Ako nije uspešno otvorena izlazna datoteka, izaći iz programa sa status kodom 3

  • Ako nije uspešno alocirana memorija za elemente, izaći iz programa sa status kodom 4

Primer poziva programa:

./a.out strukture.txt 1000

Primer ulazne datoteke strukture.txt:

Niz 52 n
Binarno_stablo_pretrage 72 log
Jednostruko_spregnuta_lista 64 n
Hes_tabela 64 1
Dvostruko_spregnuta_lista 72 n
AVL_stablo 80 log

Ispis programa na standardnom izlazu:

Prosecno vreme pretrage:
Niz - 5000 ns
Binarno_stablo_pretrage - 34.54 ns
Jednostruko_spregnuta_lista - 5000 ns
Hes_tabela - 5 ns
Dvostruko_spregnuta_lista - 5000 ns
AVL_stablo - 34.54 ns

Primer izlazne datoteke memorija.txt:

Niz 50.78kB
Binarno_stablo_pretrage 70.31kB
Jednostruko_spregnuta_lista 62.50kB
Hes_tabela 62.50kB
Dvostruko_spregnuta_lista 70.31kB
AVL_stablo 78.12kB

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <stdlib.h>
  4#include <math.h>
  5
  6#define MAX_NAZIV 41
  7#define MAX_SEARCH 4
  8
  9typedef struct cvor_st {
 10    char naziv[MAX_NAZIV];
 11    int mem;
 12    char search[MAX_SEARCH];
 13    struct cvor_st *sledeci;
 14} CVOR;
 15
 16FILE *safe_fopen(char *ime, char *rezim, int kod_greske);
 17void inicijalizacija(CVOR **glava);
 18void ucitavanje(CVOR **glava, FILE *pf);
 19CVOR *napravi_cvor(char *ime, int m, char *alg);
 20void dodaj_na_kraj(CVOR **glava, CVOR *novi);
 21void ispis_memorija(FILE *pf, CVOR *glava, int uneta_vel);
 22void ispis_trajanja(CVOR *glava, int uneta_vel);
 23void obrisi_listu(CVOR **glava);
 24
 25int main(int argc, char **argv) {
 26
 27    if (argc != 3) {
 28        printf("Primer poziva programa: %s strukture.txt 1000\n", argv[0]);
 29        exit(1);
 30    }
 31
 32    CVOR *glava;
 33    FILE *ulazna, *izlazna;
 34
 35    inicijalizacija(&glava);
 36    ulazna = safe_fopen(argv[1], "r", 2);
 37    ucitavanje(&glava, ulazna);
 38    fclose(ulazna);
 39
 40    izlazna = safe_fopen("memorija.txt", "w", 3);
 41    ispis_memorija(izlazna, glava, atoi(argv[2]));
 42    fclose(izlazna);
 43
 44    ispis_trajanja(glava, atoi(argv[2]));
 45    obrisi_listu(&glava);
 46
 47    return 0;
 48}
 49
 50FILE *safe_fopen(char *ime, char *rezim, int kod_greske) {
 51    FILE *pf = fopen(ime, rezim);
 52
 53    if (pf == NULL) {
 54        printf("Nije otvoren %s", ime);
 55        exit(kod_greske);
 56    }
 57
 58    return pf;
 59}
 60
 61void inicijalizacija(CVOR **glava) {
 62    *glava = NULL;
 63}
 64
 65void ucitavanje(CVOR **glava, FILE *pf) {
 66    char ime[MAX_NAZIV], alg[MAX_SEARCH];
 67    int m;
 68    
 69    while(fscanf(pf, "%s %d %s", ime, &m, alg) != EOF) {
 70        CVOR *novi = napravi_cvor(ime, m, alg);
 71        dodaj_na_kraj(glava, novi);
 72    }
 73}
 74
 75CVOR *napravi_cvor(char *ime, int m, char *alg) {
 76    CVOR *novi = (CVOR *)malloc(sizeof(CVOR));
 77
 78    if (novi == NULL) {
 79        printf("Nema dovoljno memorije!\n");
 80        exit(4);
 81    }
 82
 83    strcpy(novi->naziv, ime);
 84    strcpy(novi->search, alg);
 85    novi->mem = m;
 86    novi->sledeci = NULL;
 87
 88    return novi;
 89}
 90
 91void dodaj_na_kraj(CVOR **glava, CVOR *novi) {
 92    if (*glava == NULL) {
 93        *glava = novi;
 94    } else {
 95        CVOR *trenutni = *glava;
 96        while(trenutni->sledeci != NULL) {
 97            trenutni = trenutni->sledeci;
 98        }
 99        trenutni->sledeci = novi;
100    }
101}
102
103void obrisi_listu(CVOR **glava) {
104    while(*glava != NULL) {
105        CVOR *trenutni = *glava;
106        *glava = trenutni->sledeci;
107        trenutni->sledeci = NULL;
108        free(trenutni);
109    }
110}
111
112void ispis_memorija(FILE *pf, CVOR *glava, int uneta_vel) {
113    CVOR *tr = glava;
114    while(tr != NULL) {
115        fprintf(pf, "%s %.2lfkB\n", tr->naziv, tr->mem * uneta_vel / 1024.0);
116        tr = tr->sledeci;
117    }
118}
119
120void ispis_trajanja(CVOR *glava, int uneta_vel) {
121    CVOR *trenutni = glava;
122    printf("Prosecno vreme pretrage:\n");
123    while(trenutni != NULL) {
124        if(strcmp(trenutni->search, "1") == 0) {
125            printf("%s - %d ns\n", trenutni->naziv, 5);
126        } else if(strcmp(trenutni->search, "log") == 0) {
127            printf("%s - %.2f ns\n", trenutni->naziv, 5.0 * log(uneta_vel));
128        } else if(strcmp(trenutni->search, "n") == 0) {
129            printf("%s - %d ns\n", trenutni->naziv, 5 * uneta_vel);
130        }
131        trenutni = trenutni->sledeci;
132    }
133}