# Esercitazione 6: Stringhe, Struct e Matrici # Disclaimer! Provate a cambiare gets, fgets, scanf e vedete la differenza! controllate se funziona o meno, e provate a "rompere" i vari input. Qui sono riportate soluzioni con fflush: riprendete le slides viste ad esercitazione, e pulite il buffer come è stato evidenziato! # Esercizio 0: (STRINGHE) Anagrammi Si scriva un programma che permetta all’utente di inserire due stringhe. Il programma verifica se le stringhe sono anagrammi. **Bonus:** si analizzi il caso in cui si accettino stringhe con spazi e implementare la verifica che NON tiene conto degli spazi bianchi e del fatto che alcune lettere sono maiuscole o minuscole. ### Versione base ```c // Librerie #include <stdio.h> #include <string.h> // MACRO #define N 100 int main(int argc, char* argv[]) { // Variabili char s1[N], s2[N]; int count1[256] = {0}, count2[256] = {0}, i, len1, len2, flag = 0; // Acquisizione stringa 1 printf("Inserisci la prima stringa: "); scanf("%s", s1); fflush(stdin); // Salvo la lunghezza della prima stringa len1 = (int)strlen(s1); // Acquisizione stringa 2 printf("Inserisci la seconda stringa: "); scanf("%s", s2); // Salvo la lunghezza della seconda stringa len2 = (int)strlen(s2); // Verifico che le stirnghe abbiano la stessa lunghezza if(len1 != len2){ printf("Le stringhe inserite NON sono anagrammi.\n"); return 0; } // Conto la frequenza dei caratteri in s1 e in s2 // Nota: si usa len1 in quanto se si è arrivati fino a qui le stringhe hanno la stessa lunghezza for(i = 0; i < len1; i++){ count1[s1[i]]++; count2[s2[i]]++; } // Controllo che tutte le frequenze siano uguali for(i = 0; i < 256; i++){ if(count1[i] != count2[i]){ flag = 1; break; } } if(flag) printf("Le stringhe inserite NON sono anagrammi.\n"); else printf("Le stringhe inserite sono anagrammi.\n"); return 0; } ``` ### Versione migliorata ```c // Librerie #include <stdio.h> #include <string.h> // MACRO #define N 100 int main(int argc, char* argv[]) { // Variabili char s1[N], s2[N]; int count[256] = {0}, i, len1, len2, flag = 0; // Acquisizione stringa 1 printf("Inserisci la prima stringa: "); scanf("%s", s1); fflush(stdin); // Salvo la lunghezza della prima stringa len1 = (int)strlen(s1); // Acquisizione stringa 2 printf("Inserisci la seconda stringa: "); scanf("%s", s2); // Salvo la lunghezza della seconda stringa len2 = (int)strlen(s2); // Verifico che le stirnghe abbiano la stessa lunghezza if(len1 != len2){ printf("Le stringhe inserite NON sono anagrammi.\n"); return 0; } // Conto la frequenza dei caratteri in s1 e in s2 // Nota: si usa len1 in quanto se si è arrivati fino a qui le stringhe hanno la stessa lunghezza for(i = 0; i < len1; i++){ count[s1[i]]++; count[s2[i]]--; } // Controllo che tutte le frequenze siano uguali for(i = 0; i < 256; i++){ if(count[i] != 0){ flag = 1; break; } } if(flag) printf("Le stringhe inserite NON sono anagrammi.\n"); else printf("Le stringhe inserite sono anagrammi.\n"); return 0; } ``` # Esercizio 1: Dati Anagrafici Si definisca un tipo di dato `DatiArchivio` contenente i seguenti dati relativi ad una persona: * Età * Altezza * Peso **Richieste** 1. Si scriva un programma in grado di memorizzare i dati relativi a 5 persone inseriti dall’utente 2. Si stampino tutti i dati anagrafici inseriti 3. Si stampino i dati anagrafici relativi a persone con al più 20 anni 4. Si stampi l’altezza media di tutti dati inseriti 5. Si stampi l’altezza media dei soli dati inseriti relativi a persone con almeno 30 anni ```c #include <stdio.h> #define N 5 int main(int argc, char* argv[]) { // Tipo typedef struct { int eta; int altezza; int peso; } DatiArchivio; // Variabili DatiArchivio persone[N]; int i, n_30_anni; float a_media; // Acquisizione dati for(i=0; i<N; i++){ printf("Persona %d\n", i+1); do { printf("Inserisci età: "); scanf("%d", &persone[i].eta); } while(persone[i].eta < 0); do { printf("Inserisci altezza: "); scanf("%d", &persone[i].altezza); } while(persone[i].altezza < 0); do { printf("Inserisci peso: "); scanf("%d", &persone[i].peso); } while(persone[i].peso < 0); } // Stampa di tutti i dati printf("\nTUTTI\n"); for(i=0; i<N; i++) printf("Persona %d: età = %d - altezza = %d - peso = %d\n", i+1, persone[i].eta, persone[i].altezza, persone[i].peso); // Stampa di dati con età <= 20 printf("\nPERSONE CON ETA <= 20\n"); for(i=0; i<N; i++){ if(persone[i].eta <= 20) printf("Persona %d: età = %d - altezza = %d - peso = %d\n", i+1, persone[i].eta, persone[i].altezza, persone[i].peso); } // Altezza media di tutti printf("\nALTEZZA MEDIA di TUTTI\n"); a_media = 0; for(i=0; i<N; i++) a_media += persone[i].altezza; a_media /= N; printf("Altezza media: %.2f\n", a_media); // Altezza media di persone con anni >= 30 printf("\nALTEZZA MEDIA di PERSONE CON ETA >= 30\n"); a_media = 0; n_30_anni = 0; for(i=0; i<N; i++){ if(persone[i].eta >= 30){ a_media += persone[i].altezza; n_30_anni++; } } a_media /= n_30_anni; printf("Altezza media di persone con almeno 30 anni: %.2f\n", a_media); return 0; } ``` --- # Esercizio 2: Confronto Articoli Si definisca un tipo di dato `Articolo` composto dai seguenti campi: * Titolo (stringa con spazi) * Numero di Citazioni (int) * Numero di Autori (int) * Cognome Autore Principale (stringa no spazi) **Richieste** 1. Si scriva un programma in grado di memorizzare i dati relativi a 5 articoli, da dati inseriti dall’utente 1. Si stampi il cognome dell’autore principale dell’articolo con il titolo più lungo tra quelli inseriti 1. Si inizializzi staticamente (i.e., direttamente nel codice) una variabile articolo con i seguenti valori nei rispettivi campi: * Titolo: “An Amazing Research” * N. Citazoni: 1000 * N. Autori: 5 * Cognome Autore Principale: “Magri” 1. Per ogni articolo inserito dall’utente, stampare i dati dei soli articoli con un numero di citazioni maggiori o uguali a quelle dell’articolo inizializzato staticamente 1. Si modifichi la struttura in modo tale che si salvi anche la lista dei cognomi degli autori (senza ripetere l’autore principale) 1. Si stampi il numero di autori medio degli articoli inseriti dall’utente con autore principale 1. Si stampi il numero di autori medio degli articoli inseriti dall’utente aventi almeno un autore in comune con l’articolo inizializzato staticamente ```c #include <stdio.h> #include <string.h> #define N 5 #define LEN 100 int main(int argc, char* argv[]) { // Tipo typedef char stringa[LEN]; typedef struct { stringa titolo; int n_cit; int n_autori; stringa autore; stringa altri_autori[LEN]; } Articolo; // Variabili Articolo articoli[N], articolo_statico; int i, idx_titolo_lungo, max_len, j, n_aut_medio_N; float n_aut_medio; // Acquisizione dati for (i=0; i<N; i++) { printf("Dati articolo %d\n", i+1); printf("Titolo: "); gets(articoli[i].titolo); do { printf("Citazioni: "); scanf("%d", &articoli[i].n_cit); } while(articoli[i].n_cit < 0); do { printf("Numero di Autori: "); scanf("%d", &articoli[i].n_autori); } while(articoli[i].n_autori < 0); printf("Cognome Autore Principale: "); scanf("%s", articoli[i].autore); fflush(stdin); // serve per evitare che la prossima gets legga quello che rimane nel buffer // !! non sappiamo come si comporta l'utente !! for(j=0; j<articoli[i].n_autori-1; j++){ do { printf("Cognome Co-Autore %d: ", j+1); scanf("%s", articoli[i].altri_autori[j]); fflush(stdin); } while(!strcmp(articoli[i].autore, articoli[i].altri_autori[j])); } } // Stampo titolo più lungo max_len = 0; idx_titolo_lungo = 0; for(i=0; i<N; i++){ if(strlen(articoli[i].titolo) > max_len){ idx_titolo_lungo = i; max_len = strlen(articoli[i].titolo); } } printf("\n'%s' ha il titolo più lungo\n", articoli[idx_titolo_lungo].titolo); // Inizializzo l'articolo statico strcpy(articolo_statico.titolo, "An Amazing Research"); articolo_statico.n_cit = 1000; articolo_statico.n_autori = 1; strcpy(articolo_statico.autore, "Magri"); // Stampo Dati di articoli con più citazioni dell'articolo statico printf("\nARTICOLI CON PIU CIT DELL'ARTICOLO STATICO\n"); for(i=0; i<N; i++){ if(articoli[i].n_cit > articolo_statico.n_cit){ printf("Titolo: %s\nCitazioni: %d\nN. Autori: %d\nAutore: %s\n", articoli[i].titolo, articoli[i].n_cit, articoli[i].n_autori, articoli[i].autore); for(j=0; j<articoli[i].n_autori-1; j++){ printf("Co-Autore %d: %s\n", j+1, articoli[i].altri_autori[j]); } } } // Stampo il numero medio di autori printf("\nN. AUTORI MEDIO\n"); n_aut_medio = 0; n_aut_medio_N = 0; for(i=0; i<N; i++){ n_aut_medio += articoli[i].n_autori; } n_aut_medio /= N; printf("%.2f\n", n_aut_medio); // Stampo il numero medio di autori di articoli in cui ha partecipato Magri printf("\nN. AUTORI MEDIO DI ARTICOLI IN CUI HA PARTECIPATO MAGRI\n"); n_aut_medio = 0; n_aut_medio_N = 0; for(i=0; i<N; i++){ if(!strcmp(articolo_statico.autore, articoli[i].autore)){ n_aut_medio += articoli[i].n_autori; n_aut_medio_N++; } else{ for(j=0; j<articoli[i].n_autori-1; j++){ if(!strcmp(articolo_statico.autore, articoli[i].altri_autori[j])){ n_aut_medio += articoli[i].n_autori; n_aut_medio_N++; } } } } n_aut_medio /= n_aut_medio_N; printf("%.2f\n", n_aut_medio); return 0; } ``` --- # Esercizio 3: Confronto Studenti Si definisca un tipo di dato `Studente` composto dai seguenti campi: * Nome (stringa no spazi) * Cognome (stringa no spazi) * Età * Sigla corso di iscrizione (stringa di 3 lettere a scelta tra “AUT”, “INF”, o “MAT”) * Media voti **Richieste** 1. Si scriva un programma in grado di memorizzare i dati relativi a 5 studenti inseriti dall’utente 1. Si stampi l’età media di tutti gli studenti 1. Si stampi l’età media di tutti gli studenti iscritti a “MAT” 1. Si stampi il nome e il cognome dello studente con la media più alta tra quelli iscritti a “INF” 1. Si modifichi la struttura in modo tale da aggiungere un campo `ultimitrevoti` che sia un array di dimensione 3 che salvi gli ultimi 3 voti registrati dallo studente. Si modifichi, se necessario, il codice scritto finora 1. Si stampino il nome ed il cognome di tutti gli studenti di “AUT” che abbiano come ultimi 3 voti registrati tutti voti maggiori o uguali di 29 ```c #include <stdio.h> #include <string.h> #define N 5 #define LEN 100 int main(int argc, char* argv[]) { // Tipo typedef char stringa[LEN]; typedef struct { stringa nome; stringa cognome; int eta; char corso[4]; float media; float ultimi_voti[3]; } Studente; // Variabili Studente studenti[N]; int i, eta_media_N, idx_max_media, j, flag; float eta_media, max_media; // Acquisizione for(i=0; i<N; i++){ printf("Studente %d\n", i+1); printf("Nome: "); scanf("%s", studenti[i].nome); fflush(stdin); printf("Cognome: "); scanf("%s", studenti[i].cognome); fflush(stdin); do { printf("Età: "); scanf("%d", &studenti[i].eta); } while(studenti[i].eta < 0); do { printf("Corso (AUT - INF - MAT): "); scanf("%s", studenti[i].corso); fflush(stdin); } while (strcmp(studenti[i].corso, "AUT") && strcmp(studenti[i].corso, "INF") && strcmp(studenti[i].corso, "MAT")); do { printf("Media: "); scanf("%f", &studenti[i].media); } while(studenti[i].media < 0 && studenti[i].media > 32); for (j=0; j<3; j++) { do { printf("Voto %d: ", j+1); scanf("%f", &studenti[i].ultimi_voti[j]); } while(studenti[i].ultimi_voti[j] < 0 && studenti[i].ultimi_voti[j] > 32); } } // Stampo età media di tutti printf("\nETA MEDIA\n"); eta_media = 0; for(i=0; i<N; i++){ eta_media += studenti[i].eta; } eta_media /= N; printf("%.2f", eta_media); // Stampo età media degli studenti MAT printf("\nETA MEDIA MAT\n"); eta_media = 0; eta_media_N = 0; for(i=0; i<N; i++){ if(!strcmp(studenti[i].corso, "MAT")){ eta_media += studenti[i].eta; eta_media_N++; } } eta_media /= eta_media_N; printf("%.2f", eta_media); // Stampo nome e cognome dello studente INF con media più alta printf("\nSTUDENTE INF CON MEDIA PIù ALTA\n"); max_media = 0; idx_max_media = -1; for(i=0; i<N; i++){ if(!strcmp(studenti[i].corso, "INF") && studenti[i].media > max_media){ max_media = studenti[i].media; idx_max_media = i; } } if(idx_max_media != -1) printf("%s - %s\n", studenti[idx_max_media].nome, studenti[idx_max_media].cognome); else printf("No studenti INF"); // Stampo nome e cognome degli studenti AUT con ultimi voti tutti >= 29 printf("\nSTUDENTE AUT CON ULTIMI VOTI SOPRA AL 29\n"); for(i=0; i<N; i++){ if(!strcmp(studenti[i].corso, "AUT")){ flag = 0; for(j=0; j<3 && flag != 1; j++){ if(studenti[i].ultimi_voti[j] < 29) flag = 1; } if(!flag) printf("%s - %s\n", studenti[i].nome, studenti[i].cognome); } } return 0; } ``` --- # Esercizio 4: Traccia e Trasposta **Testo** Si scriva un programma in grado di popolare una matrice quadrata di dimensione NxN. Durante l’inserimento, programma inserisce il valore assoluto del numero inserito dall’utente Si stampi la traccia della matrice (i.e., la somma delle componenti sulla diagonale principale) Si stampi la matrice trasposta **Esempio** $A = \left[\begin{matrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{matrix}\right]$ $Trace(A) = \sum_{i=0}^{N-1}A_{i,i} = 1 + 5 + 9 = 15$ $A^{\top} = \left[\begin{matrix} 1 & 4 & 7 \\ 2 & 5 & 8 \\ 3 & 6 & 9 \end{matrix}\right]$ ## Versione Base ```c #include <stdio.h> #define N 3 int main(int argc, char* argv[]) { // Variabili int mat[N][N], mat_T[N][N], i, j, traccia; // Popolamento matrice solo con valori assoluti for(i=0; i<N; i++){ for(j=0; j<N; j++){ printf("Inserire elemento mat[%d][%d]: ", i, j); scanf("%d", &mat[i][j]); // prendo l'opposto se necessario if(mat[i][j] < 0) mat[i][j] = -mat[i][j]; } } // Calcolo traccia traccia = 0; for(i=0; i<N; i++){ traccia += mat[i][i]; } printf("Traccia: %d\n", traccia); // Traspongo for(i=0; i<N; i++){ for(j=0; j<N; j++){ mat_T[i][j] = mat[j][i]; } } // Stampo trasposta for(i=0; i<N; i++){ for(j=0; j<N; j++){ printf("%d ", mat_T[i][j]); } printf("\n"); } return 0; } ``` ## Versione Ottimizzata ```c #include <stdio.h> #define N 3 int main(int argc, char* argv[]) { // Variabili int mat[N][N], mat_T[N][N], i, j, traccia; // Popolamento matrice solo con valori assoluti traccia = 0; for(i=0; i<N; i++){ for(j=0; j<N; j++){ printf("Inserire elemento mat[%d][%d]: ", i, j); scanf("%d", &mat[i][j]); // prendo l'opposto se necessario if(mat[i][j] < 0) mat[i][j] = -mat[i][j]; // Calcolo traccia if(i == j) traccia += mat[i][j]; // popolo trasposta mat_T[j][i] = mat[i][j]; } } printf("Traccia: %d\n", traccia); // Stampo trasposta for(i=0; i<N; i++){ for(j=0; j<N; j++){ printf("%d ", mat_T[i][j]); } printf("\n"); } return 0; } ``` --- # Esercizio 5: Matrice Diagonalmente Dominante Una matrice quadrata si dice diagonalmente dominante se, per ogni riga, la somma dei valori assoluti degli elementi della riga, escluso l’elemento delle riga sulla diagonale principale, è minore del valore assoluto dell’elemento sulla diagonale principale della riga. Scrivere un programma che permetta di inserire i valori di una matrice NxN e che verifichi se sia dominante o meno. **Esempio** $\left[\begin{matrix} 10 & 1 & -2\\ -1 & 10 & 2\\ 3 & 5 & 10 \end{matrix}\right]$ è dominante $\left[\begin{matrix} 10 & 1 & -2\\ -15 & 10 & 2\\ 3 & 25 & 10 \end{matrix}\right]$ NON è dominante ```c // Librerie #include <stdio.h> // MACRO #define N 3 int main(int argc, char* argv[]) { // Variabili int mat[N][N], i, j, somma, abs, flag = 0; // Acquisizione Matrice for(i=0; i<N; i++){ for(j=0; j<N; j++){ printf("Inserire l'elemento in riga %d e colonna %d: ", i+1, j+1); scanf("%d", &mat[i][j]); } } // Verifica che sia diagonalmente dominante for(i=0; i<N; i++){ // sommo i valori assoluti degli elementi tranne che di mat[i][i] somma = 0; for (j=0; j<N; j++) { if(i!=j){ abs = mat[i][j]; if(abs<0) abs = -abs; somma += abs; } } // prendo il valore assoluto di mat[i][i] abs = mat[i][i]; if(abs < 0) abs = -abs; // controllo se non è dominante if(somma > abs){ flag = 1; break; } } // Stampa Matrice if(flag) printf("Non dominante\n"); else printf("Dominante\n"); return 0; } ``` --- # Esercizio 6: Numero di Claque Una claque di una matrice NxM è una sottomatrice 2x2 tale che la somma degli elementi della sua diagonale principale sia uguale alla somma degli elementi della contro-diagonale. Si scriva un programma che prenda in input una matrice e che stampi il numero di claque della matrice stessa. ![Screenshot_2024-10-17_alle_17.12.16](https://hackmd.io/_uploads/SJjQlwflyg.png) ```c // Librerie #include <stdio.h> // MACRO #define N 3 #define M 3 int main(int argc, char* argv[]) { // Variabili int a[N][M], i, j, somma1, somma2, n_claque = 0; // Acquisizione Matrice for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("Inserire l'elemento di A in riga %d e colonna %d: ", i+1, j+1); scanf("%d", &a[i][j]); } } // Conto Claque for(i=0; i<N-1; i++){ for(j=0; j<M-1; j++){ somma1 = a[i][j] + a[i+1][j+1]; // somma diagonale somma2 = a[i][j+1] + a[i+1][j]; // somma contro-diagonale if(somma1 == somma2) n_claque++; } } // Stampo prodotto printf("La matrice inserita ha %d Claque.\n", n_claque); return 0; } ``` --- # Esercizio 7: Confronto Studenti con Matrici Modificare l’esercizio sul confronto studenti in modo tale da salvare ogni studente in una matrice di 3 righe. La prima riga della matrice ospita gli studenti di “AUT”, la seconda quelli di “INF”, la terza quella di “MAT”. Eliminare pertanto il campo sigla corso di iscrizione dalla struttura principale. Si svolgano tutti i punti dell’esercizio in questo nuovo contesto ```c #include <stdio.h> #include <string.h> #define N 5 #define LEN 100 int main(int argc, char* argv[]) { // Tipo typedef char stringa[LEN]; typedef struct { stringa nome; stringa cognome; int eta; float media; float ultimi_voti[3]; } Studente; // Variabili Studente studenti[3][N]; int i, eta_media_N, idx_max_media, j, flag, n_aut=0, n_inf=0, n_mat=0, corso, idx; float eta_media, max_media; // Acquisizione for(i=0; i<N; i++){ printf("Studente %d\n", i+1); do { printf("Che corso fa lo studente (0=AUT, 1=INF, 2=MAT)? "); scanf("%d", &corso); } while (corso < 0 || corso > 2); switch (corso) { case 0: n_aut++; idx = n_aut-1; break; case 1: n_inf++; idx = n_inf-1; break; case 2: n_mat++; idx = n_mat-1; break; default: idx = -1; break; } printf("Nome: "); scanf("%s", studenti[corso][idx].nome); fflush(stdin); printf("Cognome: "); scanf("%s", studenti[corso][idx].cognome); fflush(stdin); do { printf("Età: "); scanf("%d", &studenti[corso][idx].eta); } while(studenti[corso][idx].eta < 0); do { printf("Media: "); scanf("%f", &studenti[corso][idx].media); } while(studenti[corso][idx].media < 0 && studenti[corso][idx].media > 32); for (j=0; j<3; j++) { do { printf("Voto %d: ", j+1); scanf("%f", &studenti[corso][idx].ultimi_voti[j]); } while(studenti[corso][idx].ultimi_voti[j] < 0 && studenti[corso][idx].ultimi_voti[j] > 32); } } // Stampo età media di tutti printf("\nETA MEDIA\n"); eta_media = 0; for(i=0; i<n_aut; i++){ eta_media += studenti[0][i].eta; } for(i=0; i<n_inf; i++){ eta_media += studenti[1][i].eta; } for(i=0; i<n_mat; i++){ eta_media += studenti[2][i].eta; } eta_media /= N; printf("%.2f", eta_media); // Stampo età media degli studenti MAT printf("\nETA MEDIA MAT\n"); eta_media = 0; eta_media_N = 0; for(i=0; i<n_mat; i++){ eta_media += studenti[2][i].eta; } if(n_mat > 0){ eta_media /= n_mat; printf("%.2f", eta_media); } else{ printf("NO STUDENTI MAT\n"); } // Stampo nome e cognome dello studente INF con media più alta printf("\nSTUDENTE INF CON MEDIA PIù ALTA\n"); max_media = 0; idx_max_media = -1; for(i=0; i<n_inf; i++){ if(studenti[1][i].media > max_media){ max_media = studenti[1][i].media; idx_max_media = i; } } if(n_inf > 0) printf("%s - %s\n", studenti[1][idx_max_media].nome, studenti[1][idx_max_media].cognome); else printf("No studenti INF"); // Stampo nome e cognome degli studenti AUT con ultimi voti tutti >= 29 printf("\nSTUDENTE AUT CON ULTIMI VOTI SOPRA AL 29\n"); for(i=0; i<n_aut; i++){ flag = 0; for(j=0; j<3 && flag != 1; j++){ if(studenti[0][i].ultimi_voti[j] < 29) flag = 1; } if(!flag) printf("%s - %s\n", studenti[0][i].nome, studenti[0][i].cognome); } return 0; } ``` # Esercizio 8: Prodotto di Kronecker Il prodotto di Kronecker tra una matrice A (NxM) e B (PxQ) è una matrice (NxP)x(MxQ) definita come: $$ A\otimes B= \begin{bmatrix} a_{11}B & \cdots & a_{1n}B \\ \vdots & \ddots & \vdots \\ a_{m1}B & \cdots & a_{mn}B \\ \end{bmatrix} $$ Scrivere un programma che richieda l’inserimento di valori nelle matrici A e B, che calcoli il prodotto di Kronecker e lo stampi. ```c // Librerie #include <stdio.h> // MACRO #define N 3 #define M 3 #define P 3 #define Q 3 int main(int argc, char* argv[]) { // Variabili int a[N][M], b[P][Q], p[N*P][M*Q], i, j, k, t; // Acquisizione Matrici for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("Inserire l'elemento di A in riga %d e colonna %d: ", i+1, j+1); scanf("%d", &a[i][j]); } } for(i=0; i<P; i++){ for(j=0; j<Q; j++){ printf("Inserire l'elemento di B in riga %d e colonna %d: ", i+1, j+1); scanf("%d", &b[i][j]); } } // Prodotto di Kronecker for(i=0; i<N; i++){ for(j=0; j<M; j++){ for(k=0; k<P; k++){ for(t=0; t<Q; t++){ p[i*P + k][j*Q + t] = a[i][j] * b[k][t]; } } } } // Stampo prodotto for(i=0; i<N*P; i++){ for(j=0; j<M*Q; j++){ printf(" %d", p[i][j]); } printf("\n"); } return 0; } ``` --- # Esercizio 9: Somma Massima Sottomatrici Scrivere un programma che chiede all’utente di inserire una matrice di interi 20 × 30. Per ogni possibile dimensione B di sottomatrice quadrata, stampa un singolo intero che denota la somma massima di una sottomatrice di dimensione B x B. ```c #include <stdio.h> #define ROWS 20 #define COLS 30 int main(int argc, char* argv[]) { int matrix[ROWS][COLS]; int B, i, j, k, l, max_sum, current_sum, to_init=1; // Inserimento della matrice 20 x 30 printf("Inserisci la matrice 20 x 30 (600 numeri interi):\n"); for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { scanf("%d", &matrix[i][j]); } } // Ciclo per tutte le possibili dimensioni di sottomatrice B x B for (B = 1; B <= 20; B++) { max_sum = 0; to_init = 1; // Ciclo per trovare la sottomatrice con somma massima di dimensione B x B for (i = 0; i <= ROWS - B; i++) { for (j = 0; j <= COLS - B; j++) { current_sum = 0; // Calcola la somma della sottomatrice B x B con il vertice in (i, j) for (k = 0; k < B; k++) { for (l = 0; l < B; l++) { current_sum += matrix[i + k][j + l]; } } // Aggiorna la somma massima if (current_sum > max_sum || to_init) { max_sum = current_sum; to_init = 0; } } } // Stampa la somma massima per la dimensione B x B printf("Somma massima per sottomatrice %d x %d: %d\n", B, B, max_sum); } return 0; } ``` --- # Esercizio Visto a Lezione Questa soluzione riguarda l'esercizio a pagina 53 della lezione numero 9. **Consegna**: Si scriva un frammento di codice, che includa eventualmente anche le dichiarazioni di ulteriori variabili, che, per tutte e sole le persone che occupano un ufficio (tra quelli memorizzati nella variabile torre) orientato a sud oppure a sudEst eavente una superficie compresa tra 20 e 30 metri quadri, stampi il cognome, lo stipendio e la categoria. - Si visualizzi a schermo i numeri dei piani che non hanno neanche un ufficio esposto a nord - Dire in che piano ed in che ufficio si trova Boracchi - Copiare in un array tutti gli uffici occupati da dipendenti di categoria 5 - Copiare in un array tutti i dipendenti di categoria 5 ```c #include <stdio.h> #include <string.h> #define N_PIANI 20 #define N_UFFICI 40 typedef struct { char nome[20], cognome[20]; int stipendio; int cat; // contiene valori tra 1 e 5 int stipendio; } Impiegato; typedef struct { int superficie; /*in m^2*/ char esp[20]; Impiegato occupante; } Ufficio; int main() { // Definizione delle variabili Ufficio torre[N_PIANI][N_UFFICI]; /* edificio di 20 piani con 40 uffici per piano */ Ufficio uff1 = {15, "sudEst", {"Giacomo", "Boracchi", 2000, 5}}; torre[0][0] = uff1; Ufficio uff2 = {10, "nord", {"Andrea", "Porfiri", 1500, 3}}; torre[1][0] = uff2; int p, u; /* indice di piano nell’edificio e di ufficio nel piano */ int uffNord; /* uffNord fa da flag*/ Ufficio vett1[20 * 40]; Impiegato vett2[20 * 40]; int i, j; /* Punto 1: Stampa cognome, stipendio e categoria degli impiegati che occupano uffici a sud o a sud-est con * superficie tra 20 e 30 metri quadri */ for (p = 0; p < N_PIANI; p++) { for (u = 0; u < N_UFFICI; u++) { if ((strcmp(torre[p][u].esp, "sud") == 0 || strcmp(torre[p][u].esp, "sudEst") == 0) && torre[p][u].superficie >= 20 && torre[p][u].superficie <= 30) { printf("%s %s, stipendio: %d, categoria %d\n", torre[p][u].occupante.nome, torre[p][u].occupante.cognome, torre[p][u].occupante.stipendio, torre[p][u].occupante.cat); } } } /* Punto 2: Stampa piani senza uffici esposti a nord */ for (p = 0; p < N_PIANI; p++) { uffNord = 0; for (u = 0; u < N_UFFICI && uffNord != 1; u++) { if (strcmp(torre[p][u].esp, "nord") == 0) { uffNord = 1; } } if (uffNord == 0) { printf("Il piano %d non ha edifici esposti a nord\n", p); } } /* Punto 3: Cerca l'ufficio del Prof. Boracchi */ for (p = 0; p < N_PIANI; p++) { for (u = 0; u < N_UFFICI; u++) { if (strcmp(torre[p][u].occupante.cognome, "Boracchi") == 0 && strcmp(torre[p][u].occupante.nome, "Giacomo") == 0) { printf("L'ufficio del Prof. Boracchi è il numero %d al piano %d\n", u, p); } } } /* Punto 4: Copia uffici di dipendenti di categoria 5 in vettore */ i = 0; for (p = 0; p < N_PIANI; p++) { for (u = 0; u < N_UFFICI; u++) { if (torre[p][u].occupante.cat == 5) { vett1[i] = torre[p][u]; i++; } } } /* Punto 5: Copia dipendenti di categoria 5 in vettore */ for (j = 0; j < i; i++) { vett2[i] = vett1[j].occupante; } return 0; } ``` ---