Esercitazione 8 Array multidimensionali
Prodotto di due matrici Una matrice può essere rappresentata in C con un array bidimensionale. Consideriamo il seguente problema: date due matrici mat1[n] [P] mat2[p] [M] calcolare la matrice prodotto pmat[n] [M] i cui elementi sono definiti come segue: per i=0.. N-1, j=0.. M-1, pmat[i] [j] = Σ P-1 k=0 mat1[i] [k] * mat2[k] [j]. Il prodotto così definito si può ottenere soltanto se il numero di colonne della prima matrice è uguale al numero di righe della seconda matrice. La matrice prodotto ha N righe e M colonne.
Esempio 1 0 0 2 0 4 0 3 mat1= 22-6 3 5 2 0 mat2= 0 1 5 1 4 21 1 2 2 5 11 4 7 2 0 4 0 3 pmat= 107-3 64 0 57 10 2 30 2 23 169 11 78 18 84
PROGRAMMA /* calcolo del prodotto di due matrici */ #include <stdio.h> #define MAX_N 100 #define MAX_P 100 #define MAX_M 100 int mat1 [MAX_N] [MAX_P]; /* prima matrice */ int mat2 [MAX_P] [MAX_M]; /* seconda matrice */ int pmat [MAX_N] [MAX_M]; /* matrice prodotto */
main ( ) { int n, p, m; int i, j, k; /* richiesta delle dimensioni */ do { printf ( \ninserisci il numero di righe della prima matrice: ); scanf ( %d, &n); while ((n > MAX_N) (n < 1));
do { printf ( \ninserisci il numero di colonne della prima matrice che è uguale al numero di righe della seconda matrice: ); scanf ( %d, &p); while ((p > MAX_P) (p < 1)); do { printf ( \ninserisci il numero di colonne della seconda matrice: ); scanf ( %d, &m); while ((m > MAX_M) (m < 1)); /* fine richiesta delle dimensioni */
printf ( \n\ninizializzazione DELLA PRIMA MATRICE\n\n ); for (i=0; i < n; i++) for (j=0; j < p; j++) { printf ( Inserisci elemento riga %d colonna %d:, i, j); scanf ( %d, &mat1[i][j]); ; printf ( \n\ninizializzazione DELLA SECONDA MATRICE\n\n ); for (i=0; i < p; i++) for (j=0; j < m; j++) { printf ( Inserisci elemento riga %d colonna %d:, i, j); scanf ( %d, &mat2[i][j]); ;
/* calcolo del prodotto */ for (i=0; i < n; i++) for (j=0; j < m; j++) { /* abbiamo fissato una riga i di mat1 e una colonna j di mat2 */ ; pmat[i][j] = 0; for (k=0; k < p; k++) pmat[i][j] += mat1[i][k] * mat2[k][j]; /* la variabile k permette di scorrere contemporaneamente la riga i di mat1 e la colonna j di mat2: il suo valore varia da 0 a p */
/* visualizzazione delle matrici mat1 e mat2 */ printf ( \n\nprima MATRICE\n\n ); for (i=0; i < n; i++) { printf ( \n ); for (j=0; j < p; j++) printf ( %5d, mat1[i][j]); printf ( \n\nseconda MATRICE\n\n ); for (i=0; i < p; i++) { printf ( \n ); for (j=0; j < m; j++) printf ( %5d, mat2[i][j]);
/* visualizzazione delle matrice prodotto pmat*/ printf ( \n\nmatrice PRODOTTO\n\n ); for (i=0; i < n; i++) { printf ( \n ); for (j=0; j < m; j++) printf ( %5d, pmat[i][j]); /* fine main */
Attraversamento di una palude Questo esempio illustra i molti modi in cui è possibile manipolare gli array in C. Rappresentiamo una palude con un array bidimensionale di 0 e 1, in cui 1 rappresenta un punto attraversabile della palude, mentre 0 rappresenta un punto inaccessibile. inizio 1 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 1 0 0 0 0 fine Scriviamo un programma che, data la mappa di una palude, ne cerca un attraversamento e, se esiste, lo visualizza.
Attraversamento di una palude Consideriamo una matrice int palude[r][c] riempita di 0 o 1 Cerchiamo un cammino da sinistra a destra cioè dalla colonna 0 alla colonna C-1 Assumiamo che siano possibili solo movimenti in avanti, cioè partendo dalla posizione <riga, colonna> ci si può spostare in <riga-1, colonna+1> (solo se la riga non è la prima) <riga, colonna+1> <riga+1, colonna+1> (solo se la riga non è l ultima) Memorizziamo il cammino costruito in un array int cammino[c] che contiene gli indici delle righe corrispondenti ad ogni pezzo del percorso. Es, nel caso in figura il cammino sarà 1 2 3 3 3 2
Attraversamento di una palude #include <stdio.h> #define R 5 /* num righe, cioè larghezza della palude */ #define C 6 /* num colonne, cioè lunghezza della palude e (del cammino) */ /* Cerca un cammino a partire dalla posizione <i,j> della palude. Ritorna 1 se l'attraversamento è stato trovato, 0 altrimenti. Il cammino trovato è memorizzato nell array passato come parametro*/ int cercacammino (int palude[r][c], int i, int j, int cammino[c]); /* Cerca un cammino che porti dalla prima all'ultima colonna della palude. Ritorna 1 se l'attraversamento è stato trovato, 0 altrimenti. */ int esplorapalude (int palude [R][C], int cammino[c]); /* Visualizza una palude evidenziando un cammino attraverso asterischi.*/ void stampacammino (int palude [R][C], int cammino[c]);
int main( ){ int palude[r][c] = {{1,0,0,1,0,0, {1,0,0,0,0,0, {0,1,0,0,0,1, {0,0,1,1,1,0, {0,1,0,0,0,0; int cammino[c]; /* vettore dove memorizzare il cammino trovato */ /* ricerca del cammino */ if (esplorapalude(palude, cammino)) stampacammino(palude, cammino); else printf("non ci sono cammini che attraversano la palude\n"); return 0;
/* Cerca un cammino che porti dalla prima all'ultima colonna della palude. Ritorna 1 se l'attraversamento è stato trovato, 0 altrimenti. Il cammino trovato è memorizzato nel secondo parametro */ int esplorapalude (int palude [R][C], int cammino[c]) { int i; int trovato = 0; /* variabile booleana controlla se il cammino è stato trovato */ /* un cammino inizia con il primo elemento di una qualsiasi riga */ for (i = 0; i < R &&!trovato; i++) trovato = cercacammino(palude, i, 0, cammino); return trovato;
/* controlla se c è un cammino che inizia in posizione [ i ][ j ] */ int cercacammino (int palude[r][c], int i, int j, int cammino[c]) { int trovato = 0; /* controlla se il cammino è stato trovato */ if (palude[i][j] == 1) { /* sono sulla terraferma */ cammino[j] = i; /* aggiungo la pos. corrente nel cammino finale */ if (j == C-1) /* sono arrivato dall'altra parte della palude */ trovato = 1; else { /* cerco un passaggio nella colonna j+1 */ if (i > 0) /* non sono sulla prima riga: provo [ i-1] [ j+1 ] */ trovato = cercacammino(palude, i-1, j+1, cammino); if (! trovato ) /* provo la posizione [ i ][ j+1] */ trovato = cercacammino(palude, i, j+1, cammino); if (! trovato && i < R-1) /* non è ultima riga: provo [ i+1][ j+1]*/ trovato = cercacammino(palude, i+1, j+1, cammino); return trovato;
/* Visualizza una palude evidenziando un cammino attraverso asterischi. */ void stampacammino (int palude [R][C], int cammino[c]){ int i, j; for (i=0; i < C; i++) printf("%d ", cammino[ i ]); printf("\n\n"); printf("cammino che attraversa la palude:\n"); for (i = 0; i < R; i++) { for (j = 0; j < C; j++) { if (i == cammino[ j ]) /* se il punto fa parte del cammino */ printf("* "); /* stampa '*' */ else /* altrimenti */ printf("- "); /* stampa - */ printf("\n");