Škola jezika¶
Autor zadatka: Aleksandar Vasiljević <alexva02@uns.ac.rs>
Iz zadate ulazne datoteke učitati podatke u binarno stablo, gde struktura skola_jezika_st
sadrži sledeća polja:
naziv (jedna reč, maksimalno 30 karaktera),
grad (jedna reč, maksimalno 2 karaktera),
prvi strani jezik (jedna reč, maksimalno 15 karaktera),
drugi strani jezik (jedna reč, maksimalno 15 karaktera),
najviši nivo koji se može postići (jedna reč, maksimalno 8 karaktera),
osnovna cena kursa (realan broj),
broj polaznika po grupi (pozitivan ceo broj) i
cena sa popustom (realan broj).
Struktura skola_jezika dodatno sadrži i polja potrebna za pravilno formiranje binarnog stabla.
Binarno stablo urediti po ključu osnovna cena kurs
u opadajućem redosledu.
Iz formiranog binarnog stabla upisati podatke u zadatu izlaznu datoteku, u sledećem rasporedu polja strukture skola_jezika_st
:
naziv,
grad,
broj polaznika po grupi,
cena sa popustom (zaokružena na 3 decimale),
prvi strani jezik i
drugi strani jezik.
Cena sa popustom se izračunava na sledeći način:
ako je broj polaznika veći od 3 a manji od 7, popust iznosi 5%
Ukoliko ima 7 i/ili više od 7 a manje od 10 polaznika, cena se umanjuje za 10%
U slučaju da je broj polaznika 10 i/ili viši od 10, tada se osnovna cena kursa smanjuje za popust od 15%
U izlaznu datoteku potrebno je ispisati još i sledeće informacije:
školu stranih jezika u kojoj se nemački uči kao drugi strani jezik a čija je cena sa popustom najniža i
za odabranu školu stranih jezika (bira se na osnovu parametra
odabranaSkola
koji se prosleđuje kao argument komandne linije) ispisati koliko ima polaznika koji kao prvi strani jezik uče francuski a čija je cena kursa najviša
Primer poziva programa:
./zad Academy skole.txt izvestaj.txt
sa zadatim parametrima odabranaSkola = "Academy"
i zadatim ulazom u datoteci skole.txt
:
Academy NS engleski nemacki srednji 14800.0 7
Lingua BG nemacki francuski napredni 21099.0 10
Skill KG francuski engleski osnovni 8050.0 3
Berlitz NI engleski francuski napredni 19999.0 9
Lingua KG francuski nemacki osnovni 9020.0 2
Manhattan NS nemacki engleski napredni 20650.0 4
Academy NI francuski engleski srednji 13450.0 8
Skill BG engleski nemacki napredni 20199.0 6
Manhattan KG francuski nemacki osnovni 8345.0 12
Berlitz NS engleski francuski srednji 14200.0 5
očekivanim izlazom u datoteci izvestaj.txt
:
Lingua BG 10 17934.150 nemacki francuski
Manhattan NS 4 19617.500 nemacki engleski
Skill BG 6 19189.051 engleski nemacki
Berlitz NI 9 17999.100 engleski francuski
Academy NS 7 13320.000 engleski nemacki
Berlitz NS 5 13490.000 engleski francuski
Academy NI 8 12105.000 francuski engleski
Lingua KG 2 9020.000 francuski nemacki
Manhattan KG 12 7093.250 francuski nemacki
Skill KG 3 8050.000 francuski engleski
Skola jezika u kojoj se nemacki uci kao drugi strani jezik a cija je cena sa popustom najniza: Manhattan KG 7093.250
Broj polaznika skole Academy koji kao prvi strani jezik uci francuski a cija je osnovna cena kursa (13450.000): 8.
U slučaju da se program pozove sa prosleđenim parametrom odabranaSkola = "Akademija"
, očekivani izlaz u datoteci je:
Lingua BG 10 17934.150 nemacki francuski
Manhattan NS 4 19617.500 nemacki engleski
Skill BG 6 19189.051 engleski nemacki
Berlitz NI 9 17999.100 engleski francuski
Academy NS 7 13320.000 engleski nemacki
Berlitz NS 5 13490.000 engleski francuski
Academy NI 8 12105.000 francuski engleski
Lingua KG 2 9020.000 francuski nemacki
Manhattan KG 12 7093.250 francuski nemacki
Skill KG 3 8050.000 francuski engleski
Skola jezika u kojoj se nemacki uci kao drugi strani jezik a cija je cena sa popustom najniza:
Manhattan KG 7093.250
Nema trazene skole!
Primer rešenja¶
1// primer poziva programa:
2// ./zad Academy skole.txt izvestaj.txt
3
4#include<stdio.h>
5#include<stdlib.h>
6#include<string.h>
7#include<math.h>
8
9#define NAZIV 30+1
10#define GRAD 2+1
11#define PRVI_JEZIK 15+1
12#define DRUGI_JEZIK 15+1
13#define NIVO 8+1
14
15typedef struct skola_jezika_st {
16 char naziv[NAZIV];
17 char grad[GRAD];
18 char prviStraniJezik[PRVI_JEZIK];
19 char drugiStraniJezik[DRUGI_JEZIK];
20 char nivo[NIVO];
21 float osnovnaCenaKursa;
22 unsigned brojPolaznikaPoGrupi;
23 float cenaSaPopustom;
24 struct skola_jezika_st* levi;
25 struct skola_jezika_st* desni;
26}SKOLA;
27
28void inicijalizacija(SKOLA **koren) {
29 *koren = NULL;
30}
31
32void dodaj(SKOLA **koren, SKOLA *novi) {
33 if(*koren == NULL) {
34 *koren = novi;
35 } else if(novi->osnovnaCenaKursa >= (*koren)->osnovnaCenaKursa) {
36 dodaj(&((*koren)->levi),novi);
37 } else {
38 dodaj(&((*koren)->desni),novi);
39 }
40}
41
42SKOLA *napravi_cvor(char naziv[], char grad[], char prviStraniJezik[], char drugiStraniJezik[],
43 char nivo[], float osnovnaCenaKursa, unsigned brojPolaznikaPoGrupi) {
44 SKOLA *novi = (SKOLA *)malloc(sizeof(SKOLA));
45 if (novi == NULL) {
46 printf("\tNema dovoljno memorije!\n");
47 exit(4);
48 }
49
50 strcpy(novi->naziv, naziv);
51 strcpy(novi->grad, grad);
52 strcpy(novi->prviStraniJezik, prviStraniJezik);
53 strcpy(novi->drugiStraniJezik, drugiStraniJezik);
54 strcpy(novi->nivo, nivo);
55 novi->osnovnaCenaKursa = osnovnaCenaKursa;
56 novi->brojPolaznikaPoGrupi = brojPolaznikaPoGrupi;
57
58 //konacno
59 if(novi->brojPolaznikaPoGrupi > 3 && novi->brojPolaznikaPoGrupi < 7) { //5%
60 novi->cenaSaPopustom = novi->osnovnaCenaKursa * 0.95;
61 } else if(novi->brojPolaznikaPoGrupi >= 7 && novi->brojPolaznikaPoGrupi < 10) { //10%
62 novi->cenaSaPopustom = novi->osnovnaCenaKursa * 0.9;
63 } else if(novi->brojPolaznikaPoGrupi >= 10) {
64 novi->cenaSaPopustom = novi->osnovnaCenaKursa * 0.85;
65 } else {
66 novi->cenaSaPopustom = novi->osnovnaCenaKursa;
67 }
68
69 novi->levi = NULL;
70 novi->desni = NULL;
71
72 return novi;
73}
74
75void ucitaj(FILE *in, SKOLA **koren) {
76 char naziv[NAZIV];
77 char grad[GRAD];
78 char prviStraniJezik[PRVI_JEZIK];
79 char drugiStraniJezik[DRUGI_JEZIK];
80 char nivo[NIVO];
81 float osnovnaCenaKursa;
82 unsigned brojPolaznikaPoGrupi;
83
84 while(fscanf(in, "%s %s %s %s %s %f %u", naziv, grad, prviStraniJezik, drugiStraniJezik,
85 nivo, &osnovnaCenaKursa, &brojPolaznikaPoGrupi) != EOF) {
86 SKOLA *novi = napravi_cvor(naziv, grad, prviStraniJezik, drugiStraniJezik,
87 nivo, osnovnaCenaKursa, brojPolaznikaPoGrupi);
88 dodaj(koren, novi);
89 }
90}
91
92void ispisi_stablo(FILE *out, SKOLA *koren) {
93 if(koren != NULL) {
94 ispisi_stablo(out, koren->levi);
95 fprintf(out, "%s %s %u %.3lf %s %s\n", koren->naziv, koren->grad, koren->brojPolaznikaPoGrupi,
96 koren->cenaSaPopustom, koren->prviStraniJezik, koren->drugiStraniJezik);
97 ispisi_stablo(out, koren->desni);
98 }
99}
100
101void obrisi_stablo(SKOLA **koren) {
102 if(*koren != NULL) {
103 obrisi_stablo(&((*koren)->levi));
104 obrisi_stablo(&((*koren)->desni));
105 free(*koren);
106 *koren = NULL;
107 }
108}
109
110FILE *safe_fopen(char *imeDatoteke, char *rezim) {
111 FILE *fp = fopen(imeDatoteke, rezim);
112
113 if (fp == NULL) {
114 printf("Problem prilikom otvaranja %s datoteke!\n", imeDatoteke);
115 exit(33);
116 }
117
118 return fp;
119}
120
121SKOLA *nemackiKaoDrugiJezik(FILE *izlazna, SKOLA *koren) {
122 if (koren == NULL) {
123 return NULL;
124 }
125
126 //samo skole u kojima se nemacki uci kao drugi strani jezik
127 SKOLA *skola = NULL;
128 if(strcmp(koren->drugiStraniJezik, "nemacki") == 0) {
129 skola = koren;
130 }
131
132 //obilazak levog podstabla
133 SKOLA *skolaL = nemackiKaoDrugiJezik(izlazna, koren->levi);
134 if(skolaL != NULL) {
135 if(skola == NULL || skolaL->cenaSaPopustom < skola->cenaSaPopustom) {
136 skola = skolaL;
137 }
138 }
139
140 //obilazak desnog podstabla
141 SKOLA *skolaD = nemackiKaoDrugiJezik(izlazna, koren->desni);
142 if(skolaD != NULL) {
143 if(skola == NULL || skolaD->cenaSaPopustom < skola->cenaSaPopustom) {
144 skola = skolaD;
145 }
146 }
147
148 return skola;
149}
150
151SKOLA *polazniciFrancuski(FILE *out, SKOLA *koren, char *odabranaSkola) {
152 if(koren == NULL) {
153 return NULL;
154 }
155
156 //samo skole u kojima se francuski uci kao prvi strani jezik
157 SKOLA *skola = NULL;
158 if(strcmp(koren->naziv, odabranaSkola) == 0 && strcmp(koren->prviStraniJezik, "francuski") == 0) {
159 skola = koren;
160 }
161
162 //obilazak levog podstabla
163 SKOLA *skolaL = polazniciFrancuski(out, koren->levi, odabranaSkola);
164 if(skolaL != NULL) {
165 if(skola == NULL || skolaL->osnovnaCenaKursa > skola->osnovnaCenaKursa) {
166 skola = skolaL;
167 }
168 }
169
170 //obilazak desnog podstabla
171 SKOLA *skolaD = polazniciFrancuski(out, koren->desni, odabranaSkola);
172 if(skolaD != NULL) {
173 if(skola == NULL || skolaD->osnovnaCenaKursa > skola->osnovnaCenaKursa) {
174 skola = skolaD;
175 }
176 }
177
178 return skola;
179}
180
181int main(int brArg, char *args[]) {
182 if(brArg != 4) {
183 printf("Pogresan unos argumenata!\n");
184 exit(3);
185 }
186
187 FILE *in = safe_fopen(args[2], "r");
188 FILE *out = safe_fopen(args[3], "w");
189
190 SKOLA *koren;
191
192 inicijalizacija(&koren);
193 ucitaj(in, &koren);
194 ispisi_stablo(out, koren);
195
196 SKOLA *skolaNemacki = nemackiKaoDrugiJezik(out, koren);
197 fprintf(out, "\n\nSkola jezika u kojoj se nemacki uci kao drugi strani jezik a cija je cena sa popustom najniza: %s %s %.3lf",
198 skolaNemacki->naziv, skolaNemacki->grad, skolaNemacki->cenaSaPopustom);
199
200 SKOLA *skolaPolazniciFrancuski = polazniciFrancuski(out, koren, args[1]);
201
202 if(skolaPolazniciFrancuski)
203 fprintf(out, "\n\nBroj polaznika skole %s koji kao prvi strani jezik uci francuski a cija je osnovna cena kursa (%.3lf): %d.",
204 skolaPolazniciFrancuski->naziv, skolaPolazniciFrancuski->osnovnaCenaKursa, skolaPolazniciFrancuski->brojPolaznikaPoGrupi);
205 else
206 fprintf(out,"\n\nNema trazene skole!");
207
208 obrisi_stablo(&koren);
209
210 fclose(in);
211 fclose(out);
212
213 return 0;
214}