[C] Spiegazione frammento ciclo for

floppyes
Ciao a tutti!

Ho un problema con questo esercizio, ho la soluzione ma non riesco a capire bene come funziona!

Testo: Acquisire da tastiera una parola e visualizzare il numero di occorrenze per cui ciascuna lettera dell'alfabeto appare nella parola.

#include <stdio.h>
#define DIM 100
#define LETTERE 26
int main ()
{
   char parola[DIM];
   int i, cifre[LETTERE]={0};

   scanf("%s",parola);

   for (i=0;parola[i]!='\0' && i<DIM;i++)
      cifre[parola[i]-'a']++;

   for (i=0;i<LETTERE;i++)
      printf("Occorrenze di %c: %d\n", 'a'+i, cifre[i]);

   printf("\n");

   return 0;
}


Quello che non mi è chiaro è come fa ad ottenere la lista di tutte le lettere dell'alfabeto e tenere il conto di quante volte sono state inserite.

Il pezzo principale dovrebbe essere qua:
for (i=0;parola[i]!='\0' && i<DIM;i++)
      cifre[parola[i]-'a']++;


Di preciso cosa vorrebbe dire la composizione:
cifre[parola[i]-'a']++;


Perché cifre è un vettore di tipo int, mentre parola è di tipo char.

Grazie mille
Ciaoo :)

Risposte
hyoukarou
Per quanto riguarda i tipi, sfrutta il cast implicito.

Per ottenere la posizione della lettera invece toglie 'a', perché nella tabella dei caratteri ascii(e anche nelle altre in genere) tutte le lettere vengono una dopo l'altra:
'a' - 'a' = 97 - 97 = 0
'b' - 'a' = 98 - 97 = 1
'c' - 'a' = 99 - 97 = 2
e così via.

Un grave problema del programma sono le lettere maiuscole(e gli altri caratteri), si può rimediare facilmente usando la funzione tolower. Personalmente farei una cosa del tipo:

for (int i = 0; parola[i] != '\0' && i < DIM; ++i)
{
    char temp = tolower(parola[i]);

    if(temp < 'a' || temp > 'z')
    {
         printf("Questo è malo testo.");
         exit(0);

/* o alternativamente potresti fare una cosa tipo

         printf("Il carattere tal de tali sarà skippato perché non lettera.");
         continue;

   in modo tale da non bloccare il programma ma saltare i caratteri che non sono lettere e che provocherebbero esplosioni nucleari incontrollate
*/
    }

    cifre[temp - 'a']++;
}

vict85
Esiste la funzione isalpha per determinare se il carattere è alfabetico, che puoi far seguire da islower. Dopo di che usi un else per gestire i caratteri inaspettati.

Skylarry
Questo pezzo
cifre[parola-'a']++;

è il cuore dell'algoritmo.

Costruisce un array chiamato cifre e per ogni carattere che trova,individua una posizione univoca per ogni carattere, ricavata come indicato da hyoukarou
Per ottenere la posizione della lettera invece toglie 'a'

e somma 1 al valore precedentemente presente in quella posizione

spero di essere più chiaro qui di seguito
j=parola[i]-'a'
cifre[parola[j]]=cifre[parola[j]]+1


poi fa la scansione dell'arrai e fornisce il numero delle occorrenze per ogni carattere

floppyes
Ciao!

Scusate il ritardo nella risposta! Perfetto ora è tutto più chiaro!

Grazie ancora
Ciaoo :)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.