172 lines
5.7 KiB
C
172 lines
5.7 KiB
C
/*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 {
|
|
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;
|
|
} |