Mam napisać program, który będzie zliczał wystąpienia słów i umieszczał te słowa w drzewie alfabetycznym/ Od 3 dni męczę się z następującym kodem:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int licznik;
char* slowo;
struct Node* lewy;
struct Node* prawy;
};
typedef struct Node* Tree;
void konwersjanaslowo(char* slowo)
{
for(int i=0; slowo[i]!=0; i++)
{
if(slowo[i]>='a' && slowo[i]<='z'){slowo[i]=slowo[i]+'A'-'a';}
else
{
if(slowo[i]<'A' || slowo[i]>'Z'){slowo[i]=0; return;}
}
}
}
void kopiuj(char* slowo1, char* slowo2)
{
int i=0;
while(slowo1[i]!=0)
{
slowo2[i]=slowo1[i];
i++;
}
slowo2[i]=0;
}
short int porownaj(char* slowo1, char* slowo2)
{
int i=0;
while(slowo1[i]!=0 && slowo2[i]!=0)
{
if(slowo1[i]<slowo2[i]){return -1;}
else{if(slowo1[i]>slowo2[i]){return 1;}}
i++;
}
if(slowo1[i]==slowo2[i]){return 0;}
else
{
if(slowo1[i]==0){return -1;}
else{return 1;}
}
}
void swap(Tree ptr1, Tree ptr2)
{
Tree temp=ptr1;
ptr1=ptr2;
ptr2=temp;
}
void wstaw(char* slowo, Tree* ptr, Tree* najczestsze, int top)
{
if(*ptr==NULL)
{
*ptr=malloc(sizeof(struct Node));//!!!!!!!
(*ptr)->licznik=1;
(*ptr)->lewy=NULL;
(*ptr)->prawy=NULL;
kopiuj(slowo, (*ptr)->slowo);
if(najczestsze[top]==NULL)
{
int i=0;
while(najczestsze[i]!=NULL){i++;}
najczestsze[i]=*ptr;
}
}
else
{
if(porownaj(slowo, (*ptr)->slowo)==0)
{
(*ptr)->licznik++;
short int znaleziono=0, i=0;
while(i<top && znaleziono==0)
{
if(najczestsze[i]==(*ptr)){znaleziono=1;}
else{i++;}
}
if(znaleziono==1)
{
int k=i;
while(najczestsze[k]->licznik < (*ptr)->licznik){k--;}
k++;
if(k!=i){swap(najczestsze[k], najczestsze[i]);}
}
else
{
if(najczestsze[top]->licznik < (*ptr)->licznik)
{
while(najczestsze[top-1]->licznik < (*ptr)->licznik){top--;}
najczestsze[top]=(*ptr);
}
}
}
else
{
if(porownaj(slowo, (*ptr)->slowo)==-1){wstaw(slowo, &((*ptr)->lewy), najczestsze, top);}
else{wstaw(slowo, &((*ptr)->prawy), najczestsze, top);}
}
}
}
void zwolnij_drzewo(Tree* ptr)
{
if(*ptr!=NULL)
{
zwolnij_drzewo(&((*ptr)->lewy));
zwolnij_drzewo(&((*ptr)->prawy));
free(*ptr);
*ptr=NULL;
}
}
void wypisz(Tree* tab, int rozmiar)
{
for(int i=0; i<rozmiar; i++)
{
printf("%s %d", tab[i]->slowo, tab[i]->licznik);
}
}
int main(int argc, char *argv[])
{
int top=0;
if(argc>1)
{
for(int i=0; argv[1][i]!=0; i++)
{
top=top*10+(int)argv[1][i]-48;
}
}else{top=100;}
Tree* najczestsze=malloc(top*sizeof(Tree));
for(int i=0; i<top; i++){najczestsze[i]=NULL;}
Tree ptr=NULL;
char slowo[50];
while(scanf("%49s", slowo)!=EOF)
{
konwersjanaslowo(slowo);
wstaw(slowo, &ptr, najczestsze, top);
}
wypisz(najczestsze, top);
zwolnij_drzewo(&ptr);
free(najczestsze);
return 0;
}
Wszystko ładnie się kompiluje, ale jak próbuję to zaprząc do pracy nad plikiem:
To program mi się wysypuje. Wydaje mi się, że chodzi o zaznaczoną wykrzyknikami linijkę. Skąd te przypuszczenia? Wpisywałem instrukcję printf(“Jestem tu\n”) w różnych miejscach i kiedy wpisałem przed tą linijką, to napis wyświetlał się 2 razy. Kiedy wstawiłem za tą linijką, to napis wyświetlił się tylko raz. Stąd mój wniosek był taki, że problem powstaje przy wstawianiu drugiego słowa do drzewa. Czy ktoś może wie, dlaczego tak się dzieje?
P.S. Można pominąć część, w której program pracuje nad tablicą najczestsze, bo po okomentowaniu tego fragmentu kodu problem jest ten sam.