Newsgroup: it.comp.lang.c
Titolo: MOLTI PROBLEMI CON LISTE E PUNTATORI

/*Qualcuno sarebbe in grado di controllarmi questo semplice programmino per
calcolare la codifica di Huffman? il mio problema sta nell'unire ad una
lista un nuovo elemento. grazie mille
saluti skakka
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define N 23 /* Numero di caratteri disponibili*/
float NumeroCaratteri[N];
float ArrayOccorrenze[N];
struct albero{
 float value;
 int tag;
 struct albero *Figliodx;
 struct albero *Figliosx;
};
struct LISTA{ /* questo dovrebbe essere un ELEMENTO della lista */
 float value;
 int tag;
 struct LISTA *prev;
 struct LISTA *next;
};
struct albero *Tree;
struct LISTA *T;
struct LISTA *head;  /* puntatore alla testa della lista */
struct LISTA *tail;  /* puntatore alla coda della lista */
void Delete(struct LISTA *w);
struct LISTA *CreaLISTA(float ValoreFrequenza,int w);
struct LISTA * Insert(struct LISTA *w, float z);
   /* CalcolaOccorrenze*/
/* mi permette di leggere da input le parole digitate dall'utente e calcola
le occorrenze per ogni carattere */
CalcolaOccorrenze(){
int w;
int c;
char S[1024];
struct LISTA *L;
float ma;
float k;
k=0;
ma=0.0;
 L=(struct LISTA *) malloc(sizeof(struct LISTA));
for (w=0;w<1024;w++){
 S[w]=0;
}
for (w=0;w<N;w++){
 NumeroCaratteri[w]=0; /* annullo tutti i valori presenti nelle celle di
memoria che mi */     /* serviranno per immagazzinare i valori delle
frequenze */
}
printf("Inserire un testo terminato da INVIO");
gets(S);
for (c=0;S[c]!=0;c++){
 switch(S[c]){
  case 'a':
            NumeroCaratteri[0]= NumeroCaratteri[0]+1;
   break;
  case 'b':
            NumeroCaratteri[1]= NumeroCaratteri[1]+1;
   break;
  case 'c':
   NumeroCaratteri[2]= NumeroCaratteri[2]+1;
            break;
  case 'd':
            NumeroCaratteri[3]= NumeroCaratteri[3]+1;
            break;
  case 'e':
            NumeroCaratteri[4]= NumeroCaratteri[4]+1;
   break;
  case 'f':
   NumeroCaratteri[5]= NumeroCaratteri[5]+1;
   break;
  case 'g':
   NumeroCaratteri[6]= NumeroCaratteri[6]+1;
   break;
  case 'h':
   NumeroCaratteri[7]= NumeroCaratteri[7]+1;
   break;
  case 'i':
   NumeroCaratteri[8]= NumeroCaratteri[8]+1;
   break;
  case 'l':
   NumeroCaratteri[9]= NumeroCaratteri[9]+1;
   break;
  case 'm':
   NumeroCaratteri[10]= NumeroCaratteri[10]+1;
   break;
  case 'n':
   NumeroCaratteri[11]= NumeroCaratteri[11]+1;
   break;
  case 'o':
   NumeroCaratteri[12]= NumeroCaratteri[12]+1;
   break;
  case 'p':
   NumeroCaratteri[13]= NumeroCaratteri[13]+1;
   break;
  case 'q':
   NumeroCaratteri[14]= NumeroCaratteri[14]+1;
   break;
  case 'r':
   NumeroCaratteri[15]= NumeroCaratteri[15]+1;
   break;
  case 's':
   NumeroCaratteri[16]= NumeroCaratteri[16]+1;
   break;
  case 't':
   NumeroCaratteri[17]= NumeroCaratteri[17]+1;
   break;
  case 'u':
   NumeroCaratteri[18]= NumeroCaratteri[18]+1;
   break;
  case 'v':
   NumeroCaratteri[19]= NumeroCaratteri[19]+1;
   break;
  case 'z':
   NumeroCaratteri[20]= NumeroCaratteri[20]+1;
   break;
  case ' ':
   NumeroCaratteri[21]= NumeroCaratteri[21]+1;
   break;
  case '.':
   NumeroCaratteri[22]= NumeroCaratteri[22]+1;
   break;
  default:
   printf("Questo simbolo %c non č contemplato\n", S[c]);
   break;
 }
}      /* chiude il for */
for(w=0;w<N;w++){
 k=k+NumeroCaratteri[w];   /* numero totale di caratteri immessi */
}
for(w=0;w<N;w++){
 ArrayOccorrenze[w]=((NumeroCaratteri[w])/k); /* trovo la frequenza di ogni
carattere */
 L=CreaLISTA(ArrayOccorrenze[w],w);
}
}      /* chiude CalcolaOccorrenze */
/***************************************************************************
******/
   /* Crea la lista delle frequenze dei caratteri */
struct LISTA *CreaLISTA(float ValoreFrequenza,int w){
 struct LISTA *n1;
 n1=(struct LISTA *) malloc(sizeof(struct LISTA)); /* alloco spazio in
memoria */
 n1->tag=w;    /* associo i valori ai campi */
 n1->value=ValoreFrequenza;
 if(head==NULL){
  n1->prev=NULL;
  n1->next=NULL;
  head=n1;
  tail=n1;
 }
 if(w!=0 && w!=N-1){
  n1->prev=tail;
  tail->next=n1->prev;
 }
 if(w==1){
 head->next=n1;
 n1->prev=head;
 }
 else if(w==0){    /* se č la testa non ha precedente */
  n1->prev=NULL;
 }
 else if(w==N-1){    /* se č la coda non ha successore */
  n1->next=NULL;
 }
 tail=n1;
 return(tail);
}   /* chiudo CreaLISTA */
/***************************************************************************
*******/
struct LISTA *OrdinaLista(){
struct LISTA *P1, *P2;
struct LISTA *L;
int w=0;
 P1=(struct LISTA *) malloc(sizeof(struct LISTA)); /* alloco spazio in
memoria */
 L=(struct LISTA *) malloc(sizeof(struct LISTA));
P1->value=head->value;
P1->tag=head->tag;
P1->next=head->next;
P1->prev=head->prev;
L->value=head->value;
L->tag=head->tag;
L->next=NULL;
L->prev=NULL;
 while(w<N){
  P1=P1->next;
  while(P1->value>=L->value && L->next!=NULL){
   L=L->next;
  }
  P2=(struct LISTA *) malloc(sizeof(struct LISTA)); /* alloco spazio in
memoria */
  P2->value=P1->value;
  P2->tag=P1->tag;
  if(P2->value<L->value){
   P2->next=L;
   P2->prev=L->prev;
  }
  else{
   P2->next=L->next;
   P2->prev=L;
  }
  L=(struct LISTA *) malloc(sizeof(struct LISTA));
  L->value=P2->value;
  L->tag=P2->tag;
  L->next=P2->next;
  L->prev=P2->prev;
  while(L->prev!=NULL){
   L=L->prev;
  }
  head=L;
  w++;
 }
return(head);
}
/***************************************************************************
****/
  /* ad HUFFMAN passo la lista contenente le frequenze dei vari caratteri */
struct albero *HUFFMAN(struct LISTA *S){
int h=0;
struct albero *x, *y, *z;
struct LISTA *K;
  float p;
  float q;
  p=0.0;
  q=0.0;
  K=(struct LISTA *) malloc(sizeof(struct LISTA));
 for (h=0;h<N-2;h++){
  z=(struct albero *) malloc(sizeof(struct albero));
  x=(struct albero *) malloc(sizeof(struct albero));
  x->value=head->value;
  x->tag=head->tag;
  Delete(head);
  y=(struct albero *) malloc(sizeof(struct albero));
  p=head->value;
  y->value=p;
  y->tag=head->tag;
  Delete(head);   /* elimino dalla lista gli elementi minimi */       /*
dimodochč non possano essere piů ripresi */
  p=x->value;
  q=y->value;
  z->value=p+q;
  z->Figliodx=x;
  z->Figliosx=y;
  K=Insert(S,z->value);  /* inserisco il nuovo nodo calcolato */
 }     /* chiudo il for */
 return (K);
}      /* chiudo HUFFMAN */
/***************************************************************************
****/
void Delete(struct LISTA *w){  /* funzione che cancella l'elemento minimo
appena estratto */
struct LISTA *j;
 j=(struct LISTA*) malloc(sizeof(struct LISTA));
 j=w->next;
 head=j;
 j->prev=NULL;
 w->next=NULL;
 w->prev=NULL;
 w->tag=0;
 w->value=0.0;
}    /* chiudo Delete */
/***************************************************************************
****/
struct LISTA * Insert(struct LISTA *w, float z){ /* funzione che inserisce
il nodo appena creato */
struct LISTA *j;
 j=(struct LISTA *) malloc(sizeof(struct LISTA));
while(z>=w->value ){
 w=w->next;
 }
 j->value=z;
 j->next=w;
 j->prev=w->prev;
 w->prev=j;
 if(j->prev==NULL)
  head=j;
 if(j->next==NULL && j->prev==NULL){
  head=j;
 }
return(head);
}
/**********************************************/
struct albero * main(void){
 head=(struct LISTA *) malloc(sizeof(struct LISTA));
 tail=(struct LISTA *) malloc(sizeof(struct LISTA));
head=NULL;
T=(struct LISTA *) malloc(sizeof(struct LISTA));
CalcolaOccorrenze();
T=OrdinaLista(head);
Tree=(struct albero *) malloc(sizeof(struct albero));
Tree=HUFFMAN(T);   /* chiamo la procedura Huffman che mi genera l'albero */
       /* che calcola la codifica dei caratteri(per quel testo) */
return(Tree);
exit(0);
}    /* chiudo main */
/***************************************************************************
********/
--
Daniele Scaccabarozzi
via Fermi 4
23898 Imbersago Lc
Tel.0399920781
Mailto: 
daniele.sc...@email.it

DANIELE SCACCABAROZZI wrote:
 > /*Qualcuno sarebbe in grado di controllarmi questo semplice
 > programmino
  <tagli vari>
 > #include <stdio.h>
 > #include <stdlib.h>
 > #include <ctype.h>
 > #include <string.h>
 > #define N 23 /* Numero di caratteri disponibili*/
 > float NumeroCaratteri[N];
 > float ArrayOccorrenze[N];
sei sicuro che questi array globali siano strettamente necessari?
 >    /* CalcolaOccorrenze*/
 >
 > /* mi permette di leggere da input le parole digitate dall'utente e
 > calcola le occorrenze per ogni carattere */
 >
 > CalcolaOccorrenze(){
sei sicuro che sia il miglior prototipo che puoi dare a questa 
procedura? potresti ad esempio togliere gli array globali e passare i 
rispettivi puntatori.
 >  L=(struct LISTA *) malloc(sizeof(struct LISTA));
e` inutile, per non dire deleterio, castare il valore di ritorno di 
malloc (stiamo parlando di C, non di C++), quindi rimuovi tutti i cast.
Peraltro dimentichi di controllare il valore di ritorno in questo modo:
if (L == NULL) {
     fprintf(stderr, "Memoria esaurita.\n");
     exit(EXIT_FAILURE);
}
 >  /* ad HUFFMAN passo la lista contenente le frequenze dei vari
 > caratteri */
 >
 >struct albero *HUFFMAN(struct LISTA *S){
 >
 >int h=0;
 >struct albero *x, *y, *z;
 >struct LISTA *K;
 >
 > return (K);
 >
 >}      /* chiudo HUFFMAN */
HUFFMAN deve ritornare un puntatore a struct albero, non struct LISTA.
 > gets(S);
gets e` pericolosissima. Metti invece:
fgets(S, 1024, stdin);
 > /**********************************************/
 >
 > struct albero * main(void){
 >
 >  head=(struct LISTA *) malloc(sizeof(struct LISTA));
 >  tail=(struct LISTA *) malloc(sizeof(struct LISTA));
 >
 >
 > head=NULL;
 >
 > T=(struct LISTA *) malloc(sizeof(struct LISTA));
 >
 > CalcolaOccorrenze();
 >
 > T=OrdinaLista(head);
 >
 > Tree=(struct albero *) malloc(sizeof(struct albero));
 >
 > Tree=HUFFMAN(T);   /* chiamo la procedura Huffman che mi genera
 > l'albero che calcola la codifica dei caratteri(per quel testo) */
 > return(Tree);
 >
 > exit(0);
 >
 > }    /* chiudo main */
povero main... scrivere qualcosa del tipo int main() {... return 0;}
proprio no, eh?
e poi, sei sicuro di cosa fai fare al puntatore head? prima lo fai 
puntare ad uno spazio allocato dinamicamente, subito dopo gli assegni NULL.
Non escludo che mi siano sfuggite altre correzioni.
Infine vorrei dirti una cosa: cerca anche di metterti nei panni di chi 
deve leggere il tuo articolo su Usenet. Se rendi il tuo messaggio piu` 
leggibile, faciliti la vita agli altri utenti ed hai piu` possibilita` 
di ricevere risposte. Quindi la prossima volta indenta il tuo codice e 
limitati a postarne le parti piu` rilevanti.
-- 
ciao,
     Giuseppe