kod_bez_buggov/program.c

172 lines
5.7 KiB
C
Raw Normal View History

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;
}