2019-05-12 15:15:44 +00:00
/*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 <stdio.h>
# include <stdlib.h>
# include <string.h>
# 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 {
2019-05-12 18:08:22 +00:00
char slovo [ 20 ] ;
2019-05-12 15:15:44 +00:00
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
2019-05-12 18:08:22 +00:00
comp = strcmp ( word , temp - > slovo ) ;
2019-05-12 15:15:44 +00:00
//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 {
2019-05-12 18:08:22 +00:00
temp = temp - > left ;
2019-05-12 15:15:44 +00:00
}
}
//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
2019-05-12 18:08:22 +00:00
if ( zobraz - > count > 1 & & vypisane = = 0 ) {
2019-05-12 15:15:44 +00:00
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 ;
}