Your SlideShare is downloading. ×
06 2 vector_matrici
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

06 2 vector_matrici

140
views

Published on

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
140
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
1
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Fondamenti di informatica Vettori e matrici
  • 2. Ancora sulle sequenze • il costruttore di tipo array permette di definire sequenze di elementi di qualsiasi tipo base di lunghezza predefinita • Il tipo di libreria string permette di definire sequenze di caratteri di lunghezza variabile • E se serve sequenza di di qualsiasi tipo base di lunghezza variabile • Si usa il tipo template vector<>
  • 3. Vector<> • Definito in libreria (#include <vector>) • E' un tipo template di classe (class template) – Detto anche "generico" • Template = esempio, prototipo • Significa che il vettore definisce il funzionamento della sequenza, a prescindere dal tipo di contenuto • Il tipo template va istanziato per ottenere un tipo effettivamente utilizzabile – vector<int>: tipo vettore di interi – vector<bool>: tipo vettore di interi – ecc..
  • 4. Inizializzazione di un vettore • Se indichiamo con T un tipo base o composto • Esempio: vector<string> versi = {"nel", "mezzo", "del"}; • Esempio: tutte le forme di inizializzazione
  • 5. Esempi vector<int> ivec; // initially empty vector<int> ivec2(ivec); // copy elements of ivec into ivec2 vector<int> ivec3 = ivec; // copy elements of ivec into ivec3 vector<string> articles = {"a", "an", "the"}; //copy list initialization vector<string> v1{"a", "an", "the"}; // direct list initialization vector<string> svec(10, "hi!"); // 10 strings; each element is "hi!" vector<int> ivec(10); //10 elements initialized to 0 (default for int) vector<string> svec(10); // ten elements, each an empty string • Attenzione alle parentesi! vector<int> vector<int> vector<int> vector<int> v1(10); // v2{10}; // v3(10, 1); v4{10, 1}; v1 v2 // // has ten elements with value 0 has one element with value 10 v3 has ten elements with value 1 v4 has two elements with values 10 and 1
  • 6. Inizializzazione: () vs {} vs = • Regola generale: • () indica la chiamata del "costruttore" del tipo classe, – come vedremo, a tale chiamata possono rispondere costruttori che accettano input diversi, per cui le (…) possono essere usate con differenti contenuti (10, "ciao"), (10), (vett1) … • = indica l'inizializzazione per copia: a destra del = deve esserci un oggetto il cui contenuto può essere copiato nell'oggetto di sinistra • {} indica l'inizializzazione tramite una lista di valori, deve sempre contenere uno o più valore "legali", cioè di tipo ammissibile come contenuto
  • 7. Aggiungere elementi a un vettore • I tipi vector sono comodi in quanto permettono di aggiungere elementi alla sequenza in modo dinamico • Si usa la funzione push_back() int main() { vector<string> testo; string parola; cout << "Inserire un testo, ctl-z per finire" << endl; while (cin >> parola) testo.push_back(parola); for (auto p : testo) // per ogni parola cout << p << endl; // stampa parola e va a capo return 0; }
  • 8. Estensione dinamica dei vettori • E' un'operazione comoda ed efficiente • Serve ogniqualvolta non è nota la dimensione del vettore e non ci sono elementi per inizializzarlo in modo sensato • Ha un limite: non si può usare push_back all'interno di un ciclo range for – Il ciclo range for itera su tutti gli elementi e necessita che l'estensione del vettore NON cambi
  • 9. Altre operazioni sui vettori • Del tutto simili a quelle su string
  • 10. Prodotto scalare di due vettori
  • 11. Codice #include <iostream> #include<vector> using namespace std; int main() { vector<int> a, b; int valore, lunghezza, prodotto = 0; cout << endl << "Inserisci la lunghezza cin >> lunghezza; cout << endl << "Inserisci gli elementi for (int i = 0; i < lunghezza; ++i) { cin >> valore; a.push_back(valore); } cout << endl << "Inserisci gli elementi for (int i = 0; i < lunghezza; ++i) { cin >> valore; b.push_back(valore); prodotto += a[i] * b[i]; } cout << "Il prodotto scalare vale: " << return 0; } dei vettori: " << endl; di a: " << endl; di b: " << endl; prodotto << endl;
  • 12. Check this out ! • Perché non funziona usare due volte (while cin>>valore) per leggere i due vettori uno dopo l'altro – http://stackoverflow.com/questions/11095291/re using-stdcin-after-eof • Perché l'input in C++ non è semplice – http://www.cplusplus.com/forum/articles/6046/
  • 13. Coseno di similitudine
  • 14. Codice sorgente #include <iostream> #include<vector> #include<cmath> using namespace std; int main() { vector<int> a, b; float valore, prodotto = 0.0, normaA = 0.0, normaB = 0.0, coseno=0.0; int lunghezza=0; cout << endl << "Inserisci la lunghezza dei vettori: " << endl; cin >> lunghezza; cout << endl << "Inserisci gli elementi di a: " << endl; for (int i = 0; i < lunghezza; ++i) { cin >> valore; a.push_back(valore); normaA += valore * valore; } cout << endl << "Inserisci gli elementi di b: " << endl; for (int i = 0; i < lunghezza; ++i) { cin >> valore; b.push_back(valore); normaB += valore * valore; prodotto += a[i] * b[i]; } coseno = prodotto/(sqrt(normaA)*sqrt(normaB)); // sqrt definita in cmath cout << "Il prodotto scalare vale: " << prodotto << endl; cout << "La norma di A vale: " << normaA << endl; cout << "La norma di B vale: " << normaB << endl; cout << "Il coseno di similitudine vale: " << coseno << endl; return 0; }
  • 15. Confronto vettore-array • In un array il numero di elementi è fisso, in un vettore è definito da inizializzazione e aggiunta dinamica di elementi • [] non si usa con i vettori per aggiungere elementi (tantomeno con gli array a cui NON si può per definizione aggiungere) vector<int> ivec; // vuoto for (decltype(ivec.size()) i = 0; i < 10; ++i) ivec[i] = i; // errore: ivec non ha elementi • Per aggiugere elementi a un vettore si usa push_back() for (decltype(ivec.size()) i = 0; i < 10; ++i) ivec.push_back(i); // ok: aggiunge elemento col valore ix
  • 16. Confronto array-vettori • [] si usa per leggere o modificare valori esistenti, sia di array sia di vettori int main() { vector<char> v = { 'a', 'b', 'c', 'd' }; v[0] = 'z'; // modifica tramite operatore [] for (auto c : v) { // lettura con range for cout << c << endl; } return 0; }
  • 17. Accesso per indice e accesso generale • Le sequenze rappresentano serie di elementi omogenei • Gli elementi possono (ma non devono necessariamente) essere memorizzati in celle di memoria contigue – Tale è il caso caso degli array • Non è sempre necessario conoscere la struttura di memorizzazione degli elementi, purché si possa accedere agli elementi – L'operatore [] permette l'accesso per indice e quindi anche la scansione sequenziale  index che va da 0 a size()-1 • Esistono altre strutture di dati per contenere insiemi di elementi che non forniscono l'accesso per indice con [] • Esiste un altro metodo di accesso, più generale di [], mediante un oggetto apposito, detto iteratore (iterator)
  • 18. Il concetto di iteratore • Iteratore = segnaposto, cursore – Tiene traccia dell'elemento di interesse della sequenza – Può essere spostato da un elemento all'altro • Si può sapere se è sul primo elemento, sull'ultimo elemento, o "fuori", cioè sulla posizione appena successiva all'ultimo elemento della sequenza – Permette di accedere al valore dell'elemento "indicato" (o "puntato") dall'iteratore v.begin() v v.end() "una posizione dopo l'ultimo elemento"
  • 19. Perché v.end() vale "uno dopo la fine"? • http://stackoverflow.com/questions/9963401/ why-are-standard-iterator-ranges-begin-endinstead-of-begin-end
  • 20. Operazioni sugli iteratori • *iter usa l'operatore di dereferenziazione * per accedere all'elemento "indicato" dall'iteratore iter • Lo vedremo di nuovo, con il costruttore di tipo puntatore
  • 21. [ ] vs iterator vs range for vector<char> v = {'a','b','c','d' }; for (decltype(v.size()) i = 0; i < v.size(); ++i) { cout << v[i] << endl; // accesso con indice } vector<char> v = {'a','b','c','d'}; for (auto c : v) { cout << c << endl; // accesso con cursore del range for } vector<char> v = {'a','b','c','d'}; for (auto i = v.begin(); i != v.end(); ++i) cout << *i << endl; // accesso con iteratore
  • 22. Check this out! • http://stackoverflow.com/questions/14373934/iterator-loop-vsindex-loop • SO wisdom  What to use? WARNING adult materials ! • For your particular example of iterating over std::vector: if you really need the index (e.g. access the previous or next element, printing/logging the index inside the loop etc.) or you need a stride different than 1, then I would go for the explicitly indexed-loop, otherwise I'd go for the range-for loop. • For generic algorithms on generic containers I'd go for the explicit iterator loop unless the code contained no flow control inside the loop and needed stride 1, in which case I'd go for the STLfor_each + a lambda.
  • 23. Altre considerazioni sulle strutture dinamiche • Operazioni che estendono le dimensioni del vettore (push_back) invalidano l'iteratore – All'interno di un ciclo basato su range for o iteratore non si devono aggiungere elementi • Iteratori su vector e string consentono ulteriori operazioni:
  • 24. Ricerca binaria con iteratore int main() { vector<string> text = { "cammin", "del", "di", "mezzo", "nel", "nostra", "vita" }; string sought; cout << "Inserire la parola cercata" << endl; cin >> sought; auto beg = text.begin(), end = text.end(); // end is one past the last auto mid = text.begin() + (end - beg) / 2; // original midpoint while (mid != end && *mid != sought) { if (sought < *mid) // is the element we want in the first half? end = mid; // if so, adjust the range to ignore the second half else // the element is in the second half beg = mid + 1; // start looking with the element just after mid mid = beg + (end - beg) / 2; // new midpoint } auto pos = mid-text.begin(); // computes the distance from the 1st elem if (*mid == sought) cout << "Parola trovata alla posizione: " << pos << endl; else cout << "Parola non trovata" << endl; return 0; }
  • 25. Come calcolare il valore dell'indice quando si usa un iteratore • http://stackoverflow.com/questions/2152986/ best-way-to-get-the-index-of-an-iterator
  • 26. Verifica della palindromicità • Cosa serve – Una parola – Due cursori • Algoritmo – – – – Leggi la parola Posiziona cursore sx sul primo elemento Posiziona cursore dx su ultimo elemento Fintantoché i due cursori indicano lettere uguali e cursore sx è < di cursore dx • Avanza cursore sx • Arretra cursore dx – Se cursore sinistro >= dx • Palindroma – Altrimenti • Non palindroma
  • 27. Codice sorgente int main() { string parola; cout << "Inserisci la parola" << endl; cin >> parola; auto inizio = parola.begin(), fine = parola.end(); --fine; // cursore di dx arretra sull'ultimo elemento while (*inizio == *fine && inizio < fine) { ++inizio; --fine; } if (inizio >= fine) // se true non riscontrati caratteri discordi cout << "La parola " << parola << " è palindroma" << endl; else cout << "La parola " << parola << " NON è palindroma" << endl; return 0; } • Varianti – Estensione alle frasi palindrome: "i topi non avevano nipoti" – Soluzione con array di char – Soluzione con altre modalità di accesso
  • 28. >> vs getline() • cin >> parola; – Legge l'input arrestandosi al primo spazio bianco – Se si inserisce "i topi non avevano nipoti" legge "i" • getline(cin, parola) – Legge l'input fino a fine riga (fino al primo carattere newline, che non viene inserito nella stringa) – Legge tutta la frase "i topi non avevano nipoti"
  • 29. Evidenziazione delle parole • Dato un file di testo codificato con caratteri ASCII e una parola specificata dall'utente, stampare – il contenuto del file con le occorrenze della parola evidenziate (p.e. in maiuscolo) e le righe numerate – I numeri di riga in cui ricorre la parola • Cosa serve – Un un numero imprecisato di stringhe, una per ogni riga del testo – La parola da evidenziare – Il contatore delle occorrenze – Un numero imprecisato interi, per memorizzare il numero delle righe in cui la parola è presente – Un indice di scorrimento sulla riga e sulla parola per confrontare se le lettere della parola cercata coincidono con quelle della riga
  • 30. Algoritmo • Associa lo standard input al file .txt • Fintantoché ci sono righe di testo – Fintantoché ci sono caratteri nella riga corrente • Cerca la lettera iniziale della parola (parola[0]) – NB: se non c'è, arrivi a fine riga e continui con la prox • Cerca se ci sono anche tutti gli altri caratteri – NB: potrebbe finire la riga prima di trovarli tutti • Controlla che la parola non sia parte di un'altra – NB: es: se cerco ERA devo escludere  invERA, vERAce N e l • Se hai trovato tutti e soli i caratteri – Metti in maiuscolo la parola dentro la riga corrente – Salva l'indice della riga in cui hai trovato la parola d e l • Quando hai finito i caratteri della riga corrente, salva la riga nel vettore di testo del risultato p i – Quando hai finito le righe • Stampa il contenuto di tutte le righe salvate • Stampa gli indici di riga a cui hai trovato la parola N e l 0 1 2 m e 3 z z o 4 6 8 5 7 d e l 9 1 0 1 1 1 2 c 1 3 a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 n o s t d i 2 0 p p o 2 1 2 2 r a n o s 2 3 t r a 2 4 2 7 2 8 2 9 2 5 2 6
  • 31. Scansione abbinata di due sequenze N e l d e l p i p p o n o s t r a indiceParola (ip) N e l 0 1 2 m e 3 z z o 4 6 8 5 7 d e l 9 1 0 1 1 1 2 c 1 3 a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 d i 2 0 2 1 2 2 n o s 2 3 t r a 2 4 2 7 2 8 2 9 2 5 2 6 indiceRiga (ir) riga.size=30 • Cerca la lettera iniziale della parola – ip=0; – Fintantoché indiceRiga<riga.size()&& parola [ip]!=riga[ir] • ++ir; // PS: l'indice di parola sta fermo sull'iniziale • Il ciclo può terminare in due modi – Non trovo neppure l'iniziale  ir=riga.size() • Passo alla prox riga, se c'è – Ho trovato l'iniziale  ir<riga.size() e l'iniziale sta in riga[ir] • Devo cercare le altre lettere
  • 32. Cerca i tutti i caratteri della parola d e l parola.size=3 ip N e l 0 1 2 m e 3 z z o 4 6 8 5 7 ip(finale) d e l 9 1 0 1 1 1 2 c 1 3 ir a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 d i 2 0 2 1 2 2 ir(finale) n o s 2 3 t r a 2 4 2 7 2 8 2 9 2 5 2 6 riga.size=30 • Fintantoché ir<riga.size() && ip<parola.size() && parola [ip]==riga[ir] • ++ip; ++ir; // sposto entrambi in avanti assieme • Il ciclo può terminare in 3 modi – Non trovo tutti i car perché finisce la riga ir=riga.size() • Smetto di cercare la parola e passo alla prossima riga – Trovo un car diverso  ir<=riga.size() ip<=parola.size() parola [ip]!=riga[ir] • riprendo a ricercare l'iniziale (parola[0]) a partire da ir – Li trovo tutti  ip=parola.size() • Passo al controllo di correttezza della parola • Attenzione: il valore di ip sta fuori dalla stringa parola
  • 33. Controlla se parola intera 1 d e l parola.size=3 indiceParola (ip) N e l 0 1 2 m e 3 z z o 4 6 8 5 7 d e l 9 ir- parola.size() - 1 ir- parola.size() 1 0 1 1 1 2 c 1 3 a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 d i 2 0 2 1 2 2 indiceRiga (ir) n o s 2 3 t r a 2 4 2 7 2 8 2 9 2 5 2 6 riga.size=30 • La parola è intera se valgono (in && ): – ip== parola.size // trovati tutti caratteri – ir == riga.size() || !isalpha(riga[ir]) • // fine riga o carattere corrente della riga non è una lettera – ir - parola.size() == 0 || !isalpha(riga[ir - parola.size() - 1] • // inizio riga o carattere a sx dell'iniziale non è una lettera
  • 34. Controlla se parola intera 2 n o s t r a parola.size=6 indiceParola (ip) N e l 0 1 2 m e 3 z z o 4 6 8 5 7 d e l 9 1 0 1 1 1 2 c 1 3 a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 d i 2 0 2 1 2 2 n o s 2 3 ir- parola.size() - 1 ir- parola.size() • Se la parola è intera t r a 2 4 2 7 2 8 2 9 2 5 2 6 indiceRiga (ir) riga.size=30 – ip== parola.size // trovati tutti caratteri – ir == riga.size() // NB per la regola del corto circuito non si legge il carattere oltre la fine della riga – !isalpha(riga[ir]) non viene valutata
  • 35. Controlla se parola intera 3 N e l parola.size=3 indiceParola (ip) N e l 0 1 2 m e 3 z z o 4 6 8 5 7 d e l 9 1 0 1 1 1 2 ir- parola.size() ir- parola.size() - 1 c 1 3 a m m i n 1 4 1 5 1 9 1 6 1 7 1 8 indiceRiga (ir) d i 2 0 2 1 2 2 n o s 2 3 t r a 2 4 2 7 2 8 2 9 2 5 2 6 riga.size=30 • Questo caso è particolare – ir- parola.size() – 1 potrebbe avere valore negativo, non si deve valutare, perché potrebbe mandare in overflow ir (che potrebbe essere unsigned) e quindi leggere valori indefiniti positivi – Pertanto il test viene fatto sulla lettera iniziale e non su quella precedente all'iniziale • ir - parola.size() == 0
  • 36. Strutture di dati multidimensionali • Array, stringhe e vettori realizzano strutture mono dimensionali ad accesso diretto • In modo simile sono definire strutture a più dimensioni, dette matrici • Dichiarazione di matrice 2D come array bidimensionale: • int A[20][30]; • A è una matrice di 20 • 30 elementi interi (600 variabili distinte) float F[20][20][30]; • F è una matrice 3D di 20 20 30 variabili di tipo float (12.000!)
  • 37. Matrici • In matematica, una matrice è tabella ordinata di elementi • Le matrici servono principalmente a descrivere valori che dipendono da due parametri, e per questo motivo sono ampiamente usate in matematica e in tutte le scienze
  • 38. Le Matrici • Le righe orizzontali di una matrice sono chiamate righe, mentre quelle verticali sono le colonne. • In generale, una matrice ha m righe e n colonne, dove m e n sono interi positivi fissati. Una matrice è descritta solitamente indicando con aij l'elemento posizionato alla riga i-esima e alla colonna j-esima. • I vettori (in senso matematico) sono matrici aventi una sola riga o una sola colonna. – una matrice con una sola riga è detta vettore riga, mentre una matrice con una sola colonna è detta vettore colonna.
  • 39. • LeinMatrici Qui sotto sono mostrati ordine una matrice, un vettore colonna ed un vettore riga • Se la matrice si chiama A – L'elemento posizionato nella riga i e nella colonna j può essere indicato come: Ai,j o A[i,j]. Si usa talvolta la notazione A = (ai,j) per indicare che A è una matrice e che i suoi elementi sono denotati con ai,j. – Gli elementi con i due indici di riga e di colonna uguali, cioè gli elementi della forma Ai,i costituiscono la diagonale principale della matrice.
  • 40. Somma di matrici • Due matrici A e B possono essere sommate se hanno le stesse dimensioni • La loro somma A + B è definita come la matrice i cui elementi sono ottenuti sommando i corrispettivi elementi di A e B. Formalmente: • (A + B)i,j: = Ai,j + Bi,j • Per esempio
  • 41. Moltiplicazione per uno scalare • La moltiplicazione per uno scalare è un'operazione che, data una matrice A ed un numero c (detto scalare), costruisce una nuova matrice cA, il cui elemento è ottenuto moltiplicando l'elemento corrispondente di A per c • (cA)ij: = cAi,j. Per esempio:
  • 42. Prodotto riga per colonna • Il prodotto di due matrici A e B è definito soltanto se il numero di righe di B coincide con il numero n di colonne di A. Il risultato è una matrice con lo stesso numero di righe di A e lo stesso numero di colonne di B • L’elemento di posizione (i,j) è dato dalla somma • https://www.youtube.com/watch?v=TcIYD_VPA0g&list=PLBE65C508FB741FCF
  • 43. Prodotto di matrici
  • 44. Le Matrici quadrate • Una matrice si dice quadrata se ha lo stesso numero di righe e colonne. • Una matrice quadrata ha una diagonale principale, quella formata da tutti gli elementi ai,i con indici uguali. La somma di questi elementi è chiamata traccia. • L'operazione di trasposizione trasforma una matrice quadrata A nella matrice AT ottenuta scambiando ogni ai,j con aj,i, in altre parole ribaltando la matrice intorno alla sua diagonale principale. • Una matrice tale che ai,j = aj,i è una matrice simmetrica. In altre parole, A è simmetrica se A = AT. • Se tutti gli elementi che non stanno nella diagonale principale sono nulli, la matrice è detta diagonale.
  • 45. Verifica di simmetria • Verificare se una matrice intera è simmetrica • Cose serve – Un array di array di interi – Una variabile booleana per il risultato • Simmetrica = true // ipotesi iniziale • Fintantoché ci sono righe, detta r la riga corrente – Fintantoché ci sono colonne, detta c la colonna corrente • Se matrice[r][c]!=matrice[c][r] – Simmetrica = false
  • 46. È corretto, ma… • Confronta matrice[i][j] con matrice[j][i] e, poi, anche matrice[j][i] con matrice[i][j] • Confronta matrice[i][i] con se stesso • Se trova una dissimmetria, continua con la verifica, ma è inutile Basta controllare valori di c < di r !!
  • 47. Verifica di simmetria #include <iostream> using namespace std; const int MAXDIM = 10; // massima dimensione possibile – nota a priori int main() { int dim, riga = 0, col = 0; int matrice[MAXDIM][MAXDIM]; // matrice realizzata con array di array di interi bool simmetrica = true; cout << "Inserisci un numero righe inferiore a " << MAXDIM << endl; cin >> dim; if (dim <= MAXDIM) { cout << "Inserisci " << dim * dim << " valori" << endl; for (riga = 0; riga < dim; ++riga) for (col = 0; col < dim; ++col) cin >> matrice[riga][col]; // riempimento matrice for (riga = 0; riga < dim; ++riga) // verifica simmetria for (col = 0; col < riga; ++col) // solo per gli elementi necessari if (matrice[riga][col] != matrice[col][riga]) simmetrica = false; cout << "La matrice " << (simmetrica ? "è" : "non è") << " simmetrica" << endl; } else cout << "LE DIMENSIONI DEVONO ESSERE MINORI DI " << MAXDIM << endl; return 0; } Esercizio: verifica di diagonalità
  • 48. Operatore condizionale • cond ? expr1 : expr2; • Se cond = true vale expr1, altrimenti vale expr2 cout << "La matrice " << (simmetrica ? "è" : "non è") << " simmetrica" << endl;
  • 49. Calcolo della trasposta const int MAXDIM = 4; int main() { // esempio di inizializzazione della matrice nel programma int dim=MAXDIM, riga = 0, col = 0; int matrice[MAXDIM][MAXDIM] = { {21, 1, 2, 33}, {3, 4, 6, 4}, {7, 8, 10, 5 }, {17, 18, 0, 51 }}; int matriceT[MAXDIM][MAXDIM] = { 0 }; // tutti gli elementi inizializzati a 0 for (riga = 0; riga < dim; ++riga) // calcolo della trasposta for (col = 0; col < dim; ++col) matriceT[col][riga] = matrice[riga][col]; cout << "Matrice trasposta" << endl; for (riga = 0; riga < dim; ++riga) // stampa della trasposta for (col = 0; col < dim; ++col) { cout << matriceT[riga][col] << ' '; if (col == dim - 1) cout << 'n'; // fine riga, vai a capo } return 0; }
  • 50. Inizializzazione degli array • Un array mono o multidimensionale può essere inizializzato (ma non assegnato!!) con una lista di valori int matrice[MAX][MAX] = { {21, 1, 2, 33}, {3, 4, 6, 4}, {7, 8, 10, 5 }, {17, 18, 0, 51 }}; int matrice[MAX][MAX] = { 21, 1, 2, 33, 3, 4, 6, 4, 7, 8, 10, 5 , 17, 18, 0, 51 }; • Valori mancanti sono messi a 0 int matrice[MAX][MAX] = {0}; // tutti valori a 0
  • 51. Matrici come vettori • Questo non funziona vector<vector<int>> matrice; // vettore di vettori interi cin >> dim; // leggi la dimensione for (riga = 0; riga < dim; ++riga) // leggi valori for (col = 0; col < dim; ++col) { cin >> matrice[riga][col]; // ERRORE!! • matrice[riga][col]; denota un elemento che NON esiste • Non conviene usare vettori e funzione push_back() per creare dinamicamente gli elementi della matrice • Serve l'allocazione dinamica della memoria (che vedremo più avanti)
  • 52. Check this out! • http://stackoverflow.com/questions/1833127/ two-dimensional-array-using-vector-in-cpp
  • 53. Somma di matrici c[i][j] = a[i][j] + b[i][j] 0 1 2 3 0 3 7 10 0 1 1 3 11 2 2 5 8 9 24 + 0 2 1 0 5 1 7 9 6 2 2 5 1 2 4 = 0 5 8 10 5 1 8 12 17 4 2 10 9 11 28 const int MAX=4; int main() { int dim = MAX, riga = 0, col = 0; int matrice1[MAX][MAX] = { { 1, 1, 1, 1 }, {1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } }; int matrice2[MAX][MAX] = { { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 }, { 2, 2, 2, 2 } }; int somma[MAX][MAX] = { 0 }; for (riga = 0; riga < dim; ++riga) / for (col = 0; col < dim; ++col) somma[riga][col] = matrice1[riga][col] + matrice2[riga][col]; cout << "Matrice Somma" << endl; for (riga = 0; riga < dim; ++riga) for (col = 0; col < dim; ++col) { cout << somma[riga][col] << ' '; if (col == dim - 1) cout << 'n'; } return 0; }
  • 54. Prodotto di matrici 0 1 2 0 3 7 10 1 3 11 2 2 5 8 9 24 1 1 2 0 3 4 4 3 7 0 1 0 2 3 9 6 1 2 5 1 2 5 0 11 0 3 8 7 0 1 * 2 c[1][2] =∑(a[1][k]*b[k][2]), con k = 0, ..., 3 3 0 1 2 0 1 2 0+18+ 22+6 3 4
  • 55. Codice sorgente int main() { int righe1 = 0, righe2 = 0, col1 = 0, col2 = 0, riga, col; int matrice1[MAXDIM][MAXDIM], matrice2[MAXDIM][MAXDIM], prodotto[MAXDIM][MAXDIM] = { 0 }; cout << "PRODOTTO MATRICI" << endl; cout << "Inserisci un numero righe e colonne inferiore a " << MAXDIM << " per matrice1" << endl; cin >> righe1 >> col1; cout << "Inserisci un numero righe e colonne inferiore a " << MAXDIM << " per matrice2" << endl; cin >> righe2 >> acol2; if (righe1 <= MAXDIM && righe2 <= MAXDIM && col1 <= MAXDIM && col2 <= MAXDIM && righe1 == col2) { cout << "Inserisci " << righe1 * col1 << " valori per matrice1" << endl; for (riga = 0; riga < righe1; ++riga) for (col = 0; col < col1; ++col) cin >> matrice1[riga][col]; cout << "Inserisci " << righe2 * col2 << " valori per matrice2" << endl; for (riga = 0; riga < righe2; ++riga) for (col = 0; col < col2; ++col) cin >> matrice2[riga][col]; for (riga = 0; riga < righe1; ++riga) // calcolo del prodotto for (col = 0; col < col2; ++col) for (int k = 0; k < righe2; ++k) prodotto[riga][col] += matrice1[riga][k] * matrice2[k][col]; cout << "Matrice Prodotto" << endl; for (riga = 0; riga < righe1; ++riga) // stampa del prodotto for (col = 0; col < col2; ++col) { cout << prodotto[riga][col] << ' '; if (col == col2 - 1) cout << 'n'; } } else if (righe1 == col2) cout << "DIMENSIONI DEVONO ESSERE MINORI DI " << MAXDIM << endl; else cout << "NUMERO RIGHE MATRICE1 DIVERSO NUMERO COLONNE MATRICE2" << endl; return 0; }