/*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[20]; 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(word, temp->slovo); //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->left; } } //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; }