diff --git a/program.c b/program.c new file mode 100644 index 0000000..474d5e4 --- /dev/null +++ b/program.c @@ -0,0 +1,172 @@ +/*Zo štandarného vstupu načítajte slová. Načítanie ukončite, ak nájdete koniec súboru. +Slovo je reťazec znakov, ohraničených bielym znakom (\n\t) , začiatkom alebo koncom riadka alebo súboru. +Medzi slovami sa môže nachádzať aj viac ako jeden biely znak a vstup môže obsahovať prázdny riadok. +Slová dlhšie ako 20 znakov z počítania vynechajte. + +Keď sa skončí načítavanie, vypíšte zoznam unikátnych slov a ich početnosti zotriedený podľa abecedy. + +Vo výpise sa jedno slovo môže nachádzať maximálne raz. Vo výpise vynechajte slová, ktoré sa vo vstupe nachádzali práve raz. + +Ak sa nepodarilo načítať žiadne slovo, vypíšte o tom chybovú správu s textom "CHYBA" a skončite program. + +Ak sa vo výpise neobjavilo žiadne slovo (všetky načítané slová mali početnosť menšiu ako 2), vypíšte o tom chybovú správu s textom "NIC" a skončite program. + +*/ + +#include +#include +#include +#define BUFFERSIZE 1000 + +struct database* vytvor_novu_bunku(char* word); +void pridaj_slovo(struct database* database, char* word); +void zobraz_strom(struct database* zobraz); + +struct database { + char slovo[30]; + int count; + struct database* left; + struct database* right; +}; + +struct database* database; + +int pocet = 0; +int comp = 0; + +int main(){ + //zasobnik pre data zo vstupu + char retazec[BUFFERSIZE]; + while(1){ + // nacitanie riadka zo standardneho vstupu, max. 999 znakov vratane konca riadka. + char* s = fgets(retazec,BUFFERSIZE,stdin); + // ak ma s hodnotu NULL, nacitanie konci. + if (s == NULL){ + puts("CHYBA"); + goto koniec; + } + + //definicia oddelovaca slov + char separators[] = "\n\t "; + // Identifikujem prvé slovo. + char* word = strtok(retazec,separators); + + + if(word != NULL){ + //ulozenie prveho slova do binarneho vyhladavacieho stromu + database = vytvor_novu_bunku(word); + + //printf("1.--%s--\n",word); //DEBUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG + + word = strtok(NULL,separators); + + while(word != NULL){ + //pridaj nove slovo do databazy + pridaj_slovo(database, word); + + //printf("--%s--\n",word); //DEBUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG + //nacitaj nove slovo + word = strtok(NULL,separators); + } + } + // Ak je slovo NULL, koncím spracovnaie riadka + if(word == NULL) break; + } + zobraz_strom(database); + if(pocet == 0) puts("NIC"); + + koniec: + return 0; +} + +void pridaj_slovo(struct database* database, char* word) { + //vytvor pomocny odkaz na databazu + struct database* temp = database; + + while(1) { + //porovnaj slovo s tym co je v databaze + comp = strcmp(temp->slovo, word); + + //ak sa rovna, zvys jeho pocetnost o jeden a opusti funkciu + if(comp == 0) { + temp->count++; + return; + } + + //ak sa nerovna pokracuj + else{ + //pokial je posledny porovnavany znak noveho slova mensi nez toho ulozeneho, pracuj s lavou vetvou + if(comp < 0){ + //pokial sa na lavej adrese nenachadza uz ziadna bunka, vytvor novu bunku a jej adresu uloz do odkazu na lavu vetvu. potom opusti funkciu + if(temp->left == NULL) { + temp->left = vytvor_novu_bunku(word); + return; + } + //pokial sa na lavej adrese nachadza dalsia bunka, zmen adresu z aktualnej bunky na nu a opakuj cyklus od porovnania slova + else { + temp = temp->right; + } + } + //pokial je posledny porovnavany znak noveho slova vacsi nez toho ulozeneho, pracuj s pravou vetvou + if(comp > 0) { + //pokial sa na pravej adrese nenachadza uz ziadna bunka, vytvor novu bunku a jej adresu uloz do odkazu na pravu vetvu. potom opusti funkciu + if(temp->right == NULL) { + temp->right = vytvor_novu_bunku(word); + return; + } + //pokial sa na pravej adrese nachadza dalsia bunka, zmen adresu z aktualnej bunky na nu a opakuj cyklus od porovnania slova + else { + temp = temp->right; + } + } + } + } +} + +struct database* vytvor_novu_bunku(char* word) { + //alokovanie pamate pre bunku + struct database* bunka = (struct database*) malloc(sizeof(struct database)); + + //vypis chybu pri nedostatku pamate + if(bunka == NULL) { + puts("Out of memory!\n"); + exit(1); + } + //do novo alokovanej bunky zapis nove slovo a nastav jeho pocetnost na 1 + strcpy(bunka->slovo, word); + bunka->count = 1; + bunka->left = NULL; + bunka->right = NULL; + //printf("%s\n", bunka->slovo); //DEBUGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG + return bunka; +} + +void zobraz_strom(struct database* zobraz) { + int vypisane = 0; + + //pokial je databaza prazdna vrat sa + if (zobraz == NULL) return; + + //ked vlavo je dalsia bunka vojdi do nej (zavolaj samu seba) + if(zobraz->left != NULL) zobraz_strom(zobraz->left); + //ked tam dalsia bunka nie je, a pocetnost je viac ako 1, vypis slovo a pokracuj v kontrole pritomnosti pravej bunky + else{ + if(zobraz->count > 1) { + pocet++; + printf("%s %d\n", zobraz->slovo, zobraz->count); + vypisane = 1; + } + } + //pokial ani vlavo ani vpravo nie je dalsia bunka, vyskoc vyssie -- dalsi kod sa uz nevykona + if(zobraz->left == NULL && zobraz->right == NULL) return; + + //pred tym ako pojdes kontrolovat pravu bunku a vojdes do nej, skontroluj ci pocetnost je viac ako 1 a slovo uz nebolo vypisane (kontrola pre pripad ze vlavo neboli bunky, slovo sa vypisalo, no vpravo este bunky su), vypis slovo a pokracuj v kontrole pritomnosti pravej bunky + if(zobraz->count >= 1 && vypisane == 0) { + pocet++; + printf("%s %d\n", zobraz->slovo, zobraz->count); + } + //ked vpravo je dalsia bunka, vojdi do nej (zavolaj samu seba) + if(zobraz->right != NULL) zobraz_strom(zobraz->right); + + return; +} \ No newline at end of file