Prośba o przeanalizowanie i wyłapanie błędów w kodzie

0

Witam.

Napisałem program który wczytuje z pliku tekstowego treść , wpisuje wyrazy do drzewa oraz ilość ich wystąpień(sortuje alfabetycznie) , następnie wrzuca w drugie drzewo gdzie sortuje względem wystąpień.
Na koncu program wypisuje wyraz oraz ilość wystąpień. Niestety podczas testowania zauważyłem że 2 rzeczy są nie wporządku, a z 2 muszę was prosić o pomoc.
1.program jakimś cudem wczytuje nieznany mi znak i wrzuca go w drzewo jako wyraz (prawdopodobne związane z EOF ale nie wiem jak to naprawić)
2.program wypisuje jeden z wyrazów kompletnie błędnie (traktując go jako cyfrę). Błąd znajduje się po mojej analizie gdzieś w korzeniu (tak uważam ponieważ tym wyrazem jest pierwszy który jest wczytywany zatem jest to korzeń)
3.Chcę aby program wyrzucał na ekran wyrazy ktore powtarzają się najwięcej razy , ale chcę żeby wyświetlił tylko określoną ilość (tj jeżeli np program wczyta 1000 różnych wyrazów o różnych ilościach wystąpień , to ja chcę żeby on tylko wyświetlił 100 najszęstszych). Próbowałem to zrobić tak że przechodzi przez tablicę to zwiększa zmienną o 1 za każdym razem gdy idzie do kolejnego węzła, niestety opornie to wyszło :P.
4.NIe bardzo wiem w którym momencie i w jaki sposób zwolnić tablice w takim drzewie (jakby ktoś wytłumaczył to byłbym wdzięczny :) )

Oto kod:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
    int count;
    char value[50];
    struct node *left;
    struct node *right;
};
struct node_v2
{
    int count_v2;
    char value_v2[50];
    struct node_v2 *left_v2;
    struct node_v2 *right_v2;
    int poss;	
};
void addnode(char word[],struct node *start);
void checktree(struct node *start);
void addnode_tree2(char word[],int i,struct node_v2 *start_v2);
void print_tree21(struct node_v2 *start_v2,int i);	
void print_tree22(struct node_v2 *start_v2);

struct node *root;
struct node *start;
struct node_v2 *root2;
struct node_v2 *start_v2; 
int main ()
{
	char word[50];
	int c;
	root=root2=NULL;
	FILE *fr;
	if((fr=freopen("tekst.txt","r",stdin))==NULL)
	{
		printf("error\n");
		exit(1);
	}
	while(feof(fr)==0)
	{
	        if((c=getchar())!=EOF && !((c>='a' && c<='z') || (c>='A' && c<='Z')))
		        continue;
        	int i=0;
        	if (c>='a' && c<= 'z')
        		c -= 'a'-'A';
		word[i]=c;
        	i++;
        	while((c=getchar())!=EOF && ((c>='a' && c<='z') || (c>='A' && c<='Z')))
        	{
            		if (c>='a' && c<= 'z')
                	c -= 'a'-'A';
            		word[i]=c;
            		i++;
        	}
        	word[i]='\0';
        	addnode(word,&root);    												
	}
	checktree(&root);
	print_tree21(&root2,1);
	print_tree22(&root2);
    	fclose(fr);
    	return 0;
}
 
void addnode(char word[],struct node *start)
{
 	if (root == NULL)                   											
	{
	        root=(struct node *)malloc(sizeof(root));   										
        	strcpy(root->value,word);    												
        	(root->count)=1;
        	root->left = NULL;
        	root->right = NULL;
	}
	else if(strcmp((start->value),word)<0)
	{
	        if(start->right != NULL)            										
        	{
		        addnode(word,start->right);
        	}
        	else
        	{
		        struct node *new = (struct node*)malloc(sizeof *root); 								
	        	strcpy(new->value,word);    											
	        	(new->count)=1;
	        	new->left = NULL;
	        	new->right = NULL;
			start->right=new;
	        }
	}
	else if(strcmp((start->value),word)>0)
	{
	        if(start->left != NULL)       						
        	{
        		addnode(word,start->left);
        	}
        	else
        	{
        		struct node *new = (struct node*)malloc(sizeof *root);								
       			strcpy(new->value,word);												
        		(new->count)=1;			
        		new->left = NULL;
       		 	new->right = NULL;
        		start->left=new;
        	}
        }
	else if(strcmp((start->value),word)==0)
	{
	        (start->count)+=1;
	}
}
void checktree(struct node *start)
{
	
	if((start->left) != NULL)													
		checktree(start->left);

	addnode_tree2(start->value,start->count,&root2);											 

	if((start->right) != NULL) 												
		checktree(start->right);
}

void addnode_tree2(char word[],int i,struct node_v2 *start_v2)
{
	if (root2 == NULL)                   											
	{
	        root2=(struct node_v2*)malloc(sizeof(root2));   										
        	strcpy(root2->value_v2,word);    												
        	(root2->count_v2)=i;
        	root2->left_v2 = NULL;
        	root2->right_v2 = NULL;
		root2->poss=0;
	}
	else if((start_v2->count_v2)>=i)
	{
	        if((start_v2->right_v2) != NULL)            									
        	{
		        addnode_tree2(word,i,start_v2->right_v2);
        	}
        	else
        	{
		        struct node_v2 *new_v2 = (struct node_v2*)malloc(sizeof *root2); 							
	        	strcpy((new_v2->value_v2),word);    											
	        	(new_v2->count_v2)=i;
	        	(new_v2->left_v2) = NULL;
	        	(new_v2->right_v2) = NULL;
	        	start_v2->poss=0;
			(start_v2->right_v2)=new_v2;
	        }
	}
	else if((start_v2->count_v2)<i)
	{
	        if(start_v2->left_v2 != NULL)       					
        	{
        		addnode_tree2(word,i,(start_v2->left_v2));
        	}
        	else
        	{
        		struct node_v2 *new_v2 = (struct node_v2*)malloc(sizeof *root2);							
       			strcpy((new_v2->value_v2),word);									
        		(new_v2->count_v2)=i;			
        		(new_v2->left_v2) = NULL;
       		 	(new_v2->right_v2) = NULL;
        		start_v2->poss=0;
			(start_v2->left_v2)=new_v2;
        	}
        }
}

void print_tree21(struct node_v2 *start_v2,int i)
{
	if(start_v2->right_v2 != NULL)													
	{
		print_tree21(start_v2->right_v2,i);					

		start_v2->poss=i;	
		i++;									 
 	}
	if(start_v2->left_v2 != NULL) 												
	{
		print_tree21(start_v2->left_v2,i);
		start_v2->poss=i;	
		i++;

	}

}
void print_tree22(struct node_v2 *start_v2)
{
	if(start_v2->right_v2 != NULL)													
		print_tree22(start_v2->right_v2);
	
	if((start_v2->poss)<=100)
	printf("%s %d %d\n",start_v2->value_v2,start_v2->count_v2,start_v2->poss);										 
 
	if(start_v2->left_v2 != NULL) 												
		print_tree22(start_v2->left_v2);
}

Ps.Program bedzie wczytywał pliki z pliku tekst.txt który musi znajdowac sie w tym samym folderze co program
Z góry dziękuję za pomoc :)

Przemo

0

Zobacz, praktycznie to samo zaś kilkakrotnie mniej kodu: http://4programmers.net/Forum/C_i_C++/263558-drzewa_i_wskazniki_do_nich?p=1209193#id1209193

0

Teroetycznie racja taki sam program. Jednak skoro zacząłem już w taki sposób to wolę tak to zrobić. Przeczytałem w tamtym temacie i zrozumiałem że można było pominąć dodawanie węzłów w drugim drzewie korzystająć z dodawania do pierwszego , tyle że nie za bardzo mogłem tak zrobić bo kolejne drzewo zawiera w węźle dodatkową informację (którą chciałem wykorzystać do tego aby program wydrukował tylko 100 wartości z drzewa a nie wszystkie tak jak by to normalnie miało miejsce.

  • dzięki za podlinkowanie bo przynajmniej wiem jak zwolnić teraz pamięć :)
0

Jak chcesz w tym się babrać to robisz to na własne życzenie, nie zdziw się jeżeli zabraknie chętnych na wspólne babranie się.

0

Babranie....różnica między programami jest taka że ja wczytuję konkretny plik , a w tamtym programie jest wczytywany poprzez podanie argumentu do programu. Inna różnica to pomiędzy tworzeniem drzew.Ja nie widzę możliwości żeby zrobić to inaczej , by za pomocą jednej funkcji wprowadzać pewne dane. W pierwszej funkcji dodawania przekazuję słowo i korzeń, a w drugiej już muszę przekazać słowo korzeń oraz ilość pojawień. Nie wiem może jestem głupi ale z postu który podesłałeś nie znalazłem(albo najzwyczajniej w świecie niezrozumiałem ) odpowiedzi na to jak to rozwiązać . Dodatkowo w drugim drzewie nie widzę możliwości aby bez tej drugiej struktury ( bo mam dwie różniące się tym że jedna zawiera int poss) będę w stanie wyświetlić np tylko 100 największych wyników. :(

0

Patrz tylko na konkretny post do którego prowadzi link.

0

Spróbowałem to przenalizować przez ten czas , nawet odnieść to do swojego programu ale niestety nie rozumiem co robią poszczególne linijki kodu:

void insertByWord(Tree *T,const char *word)      //O ile dobrze to rozumiem to do tej funkcji wprowadzamy wskaźnik na roota i słowo wprowadzone w jakąś tablice char?
  {
   int v;
   Node **curr=&T->root,*node;         // w tej linijce nie rozumiem co się dzieje
   while(*curr)
     {
      v=stricmp(word,(*curr)->word);
      if(v<0) curr=&(*curr)->lf;
      else if(v>0) curr=&(*curr)->rt;
      else
        {
         ++(*curr)->count;
         return;
        }
     }
   v=strlen(word);
   node=malloc(sizeof(Node)+v);
   memcpy(node->word,word,v+1);
   node->count=1;
   node->lf=node->rt=NULL;
   *curr=node;
  } 
typedef struct Node
  {
   struct Node *lf,*rt;
   unsigned count;
   char word[1];
  } Node;
typedef struct Tree { Node *root; } Tree;   //tej linijki nie rozumiem + czy konieczne jest podanie typedef tutaj?
0

Ad 1. Wskaźnik do rekordu o którym pytasz w trzecim pytaniu
Ad 2. A tak: Node **curr; curr=&(T->root); Node *node; ?
Ad 3. Jeżeli chcemy zamiast struct Tree używać jedynie Tree - to koniecznie.

0

1 i 3 rozumiem. Z 2 zrozumiałem że jest wskaźnik *curr który wskazuje na wskaźnik curr który wskazuje na strukturę (T->root) (zapewnie błędnie to rozumiem :( ) no i wskaźnik na node na koncu

0

Adres wskaźnika root w strukturze T, jeżeli zapiszemy *curr=NULL to niejako zrobimy T->root=NULL.

1 użytkowników online, w tym zalogowanych: 0, gości: 1