Matrice temperature con massimo e media per giorno e fascia oraria

Vogliamo catalogare le misurazioni delle temperature di una data settimana di sete giorni e per ogni giorno prelevare cinque campioni. Caricare una matrice con numeri decimali casuali compresi tra 10.00° e 39.99°, stamparne le evidenze. Calcolare quindi il massimo valore raggiunto su tutti i giorni/campioni raccolti mostrando anche giorno e fascia oraria interessate da tale valore. Per ogni fascia oraria, indica la media delle temperature.

L’esercizio è discretamente complesso e, soprattutto, abbastanza lungo per gli standard soliti. Procediamo per step.

Caricamento matrice con numeri decimali casuali

Questo è un esercizio sfizioso. L’alunno sicuramente è abituato per i propri test a staccare numeri random, perlopiù interi compresi in un range assegnato. Anche qui, gettiamo un seme casuale con srand(time(NULL)); per poi assegnare un valore casuale con rand(). Occhio, per assegnare il solito numero qui devo fare uno step in più perché con rand() % valore, trovo solo interi. Invece la funzione rand() in realtà tornerebbe un valore compreso tra 0 e 1 in decimali. Il che implica che posso inserire come estremo non direttamente 40 indicato come valore casuale ma inserisco %4000 così da poterlo dividere intero. Aggiungiamo 1000 per far partire le misurazioni da 10%.

void caricaMatrice (float _a[GIORNI][ORE])
{
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      _a[i][j] = float (rand () % 4000 + 1000) / 100;
    }
  }
}

La stampa

In genere non vale la pena mostrare il codice della stampa, decisamente semplice nell’impanto dell’esercizio medio. Qui approfittiamo per inserire due funzioncine predefinite di C++ e della sua libreria <iomanip> che servono per manipolare le stringhe di testo e numeri da stampare in modo ordinato e pulito a schermo.

Prima di stampare il valore della casella(i,j), fisso una stringa di 5 caratteri, che se riempiti bene, altrimenti mette un carattere ‘0’ a riempimento. La seconda funzioncina fissa la precisione a 5 cifre fisso in modo che venga stampato 2 interi, il punto e 2 decimali anche se il secondo è zero (es. 23.50). Notate il cout<<endl posto alla fine del secondo ciclo prima di ricominciare il primo. Quello serve per andare a capo nella stampa della riga.

void stampaMatrice (float _a[GIORNI][ORE])
{
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      cout <<setfill('0') << setw(5)<<setprecision(5)<< _a[i][j] << " ";
    }
    cout << endl;
  }
}

La funzione per il massimo

Diciamo che questa è la funzione che spaventa poco, affrontata decine di occasioni con i problemi con e senza i vettori classici. Unica accortezza: siccome bisogna indicare anche le coordinate del giorno con temperatura massima, occorrono due variabili in più che vengono aggiornate in automatico ogni volta che trovo un nuovo max relativo.

void calcolaTMax (float _a[GIORNI][ORE])
{
  float max = 0; //temperatura massima
  int max_i = 0; //posizioni i,j corrispondenti al max 
  int max_j = 0;
  
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      if (max <  _a[i][j])
      {
        max =  _a[i][j];
        max_i = i;
        max_j = j;
      }
    }
  } 
 cout<<"La temperatura massima è : "<<max<<endl;
 cout<<"raggiunta nel giorno "<<max_i +1 <<" nella fascia oraria "<<max_j + 1;
}

La media per colonna

Tra i problemi classici da affrontare con le matrici è quello di calcolare le medie per righe e colonne. Se per le righe è piuttosto semplice intuitivo, lo è leggermente meno per colonne. In realtà, basta invertire il senso dei cicli ovvero dei suoi estremi e di come reperire l’elemento di volta in volta utile.

void calcoloMediaFasce(float _a[GIORNI][ORE])
{
  float media = 0;
  float somma = 0;
  int colonna =0; //opzionale, tiene il conto della colonna per la stampa
  for (int i=0; i < ORE; i++)
  {
    for (int j=0; j < GIORNI; j++)
    {
      somma += _a[j][i];
    }
    media = somma / ORE;
    colonna++;
    somma = 0; //IMPORTANTE: resetta la somma al cambio della colonna
    cout<<endl;
    cout<<"il valore medio è nella fascia "<<colonna<<" è "<< media;
  }
}

Listato completo

#include <iostream>
#include <math.h>
#include <iomanip>

using namespace std;

int const GIORNI = 7;
int const ORE = 5;

void caricaMatrice (float _a[GIORNI][ORE])
{
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      _a[i][j] = float (rand () % 4000 + 1000) / 100;
    }
  }
}

void stampaMatrice (float _a[GIORNI][ORE])
{
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      cout << std::setw(5)<<setprecision(5)<< _a[i][j] << " ";
    }
    cout << endl;
  }
}

void calcolaTMax (float _a[GIORNI][ORE])
{
  float max = 0; //temperatura massima
  int max_i = 0; //posizioni i,j corrispondenti al max 
  int max_j = 0;
  
  for (int i=0; i < GIORNI; i++)
  {
    for (int j=0; j < ORE; j++)
    {
      if (max <  _a[i][j])
      {
        max =  _a[i][j];
        max_i = i;
        max_j = j;
      }
    }
  } 
 cout<<"La temperatura massima è : "<<max<<endl;
 cout<<"raggiunta nel giorno "<<max_i +1 <<" nella fascia oraria "<<max_j + 1;
}

void calcoloMediaFasce(float _a[GIORNI][ORE])
{
  float media = 0;
  float somma = 0;
  int colonna =0; //opzionale, tiene il conto della colonna per la stampa
  for (int i=0; i < ORE; i++)
  {
    for (int j=0; j < GIORNI; j++)
    {
      somma += _a[j][i];
    }
    media = somma / ORE;
    colonna++;
    somma = 0;
    cout<<endl;
    cout<<"il valore medio è nella fascia "<<colonna<<" è "<< media;
  }
}

int main() 
{
  float a[GIORNI][ORE];
  
  srand (time(NULL));
  
  caricaMatrice(a);
  stampaMatrice(a);
  
  cout <<endl;
  
  calcolaTMax(a);

  cout <<endl;
  
  calcoloMediaFasce (a);
  
  return 0;
  
}

Ultima modifica 2 Dicembre 2022