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 nanosekundilog- je potrebno 5 * log(n) nanosekundin- 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
2Ako nije uspešno otvorena izlazna datoteka, izaći iz programa sa status kodom
3Ako 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}