#include <stdio.h>
#include <string.h>
#define DIMSTR 16
#define MAXDIM 10

typedef char Stringa[DIMSTR];
typedef struct {
        Stringa s;
        int freq;
        }   modalita;

/* definizioni per trattaConteggio */
#define INSERITO 1
#define nonINSERITO 0
int trattaConteggio(modalita *am, int *nMod, Stringa s);
/* fine definizioni per trattaConteggio */

/* definizioni per maxFreq */
void maxFreq(modalita *am, int nMod,
             modalita *modMaxFreq, int *nModMax);
/* fine definizioni per maxFreq */

/* Esercizio su array e strutture
 * acquisisce da input un insieme di rilevazioni di un carattere
 * per ciascuna modalita' calcola la frequenza e poi visualizza
 * le modalita' a frequenza massima
 */
/* main */
int main(){
  #define TERM "." /* terminatore delle rilevazioni */
  modalita freqComuni[MAXDIM];
  int nc=0; /* numero di comuni distinti rilevati */
  modalita comuniMaxFreq[MAXDIM];
  int ncMax; /* numero di comuni con frequenza massima: verra'
              * inizializzato in una procedura */
  int i;
  Stringa s;
  printf("Inserire un comune ");
  scanf("%s",s);
  while (strcmp(s,TERM)) { /* acquisisce e tratta un comune */
    if (trattaConteggio(freqComuni, &nc, s)==nonINSERITO)
      printf("Comune %s non trattato per array pieno", s);
    printf("Inserire un comune (<.> per terminare) ");
    scanf("%s",s);
  }
  for (i=0;i<nc;i++) /* visualizza frequenze assolute */
    printf("Comune: %s\t - frequenza: %d\n",
           freqComuni[i].s, freqComuni[i].freq);
  maxFreq(freqComuni,nc,comuniMaxFreq,&ncMax);
  printf("\n\nComuni a frequenza massima %d\n",comuniMaxFreq[0].freq);
  for (i=0;i<ncMax;i++)
    printf("%s\n", comuniMaxFreq[i].s);
  printf("Fine lavoro, premere un tasto");
  i=getchar();
  return 0;
} /* main */

/* trattaConteggio
 * aggiorna il conteggio di frequenze assolute nell'array di
 * modalita' am trattando la stringa s
 * se s non era ancora apparsa incrementa *nMod e la inserisce
 * in coda all'array con conteggio 1, altrimenti incrementa il conteggio
 * restituisce nonINSERITO in caso di insuccesso per array pieno
 * INSERITO in caso di successo
 */
int trattaConteggio(modalita *am, int *nMod, Stringa s){
  int i=0;
  int nonTrovato=1;
  while (nonTrovato && i<*nMod) {
    nonTrovato = strcmp(s,am[i].s);
    i++;
  }
  if (nonTrovato) /* non trovato: devo inserire nuovo */
    if (*nMod<MAXDIM) { /* array non pieno: posso inserire */
      strcpy(am[*nMod].s,s);
      am[*nMod].freq=1;
      (*nMod)++;
      return INSERITO;
    } else return nonINSERITO; /* array pieno: non posso inserire */
  else { /* trovato: incremento conteggio */
    am[i-1].freq++;
    return INSERITO;
  }
} /* trattaConteggio */


void maxFreq(modalita *am, /* array di modalita' */
             int nMod,     /* numero di modalita' distinte trovate */
             modalita *modMaxFreq, /* array di modalita'
                                   * a frequenza massima */
             int *nModMax  /* numero di modalita' con frequenza
                            * massima */
             ){
  int i; /* contatore */
  modMaxFreq[0] = am[0]; /* il primo massimo va al primo posto
                          * massimo provvisorio */
  for (i=1; i<nMod; i++)
    if (am[i].freq>modMaxFreq[0].freq)
      modMaxFreq[0] = am[i]; /* aggiorna massimo provvisorio
                              * e' il massimo fra quelli incontrati
                              * finora */
  *nModMax = 0;
  for (i=0; i<nMod; i++)
    if (am[i].freq==modMaxFreq[0].freq) {
      modMaxFreq[*nModMax] = am[i];
      (*nModMax)++;
    }
} /* maxFreq */