Matrici în C++: “Tablouri cu Două Dimensiuni – Ca o Foaie de Matematica” – Materie BAC

Bun, hai să vorbim despre un concept care pare intimidant dar e de fapt foarte intuitiv: MATRICILE (Array-uri bidimensionale). Nu e doar despre tabele (cuvânt plictisitor) și grid-uri. E despre cum organizezi datele pe rânduri și coloane, exact ca într-o foaie de Excel sau ca tablele de șah. E un concept atât de natural încât dacă ai privi o matrice, ai recunoaște imediat structura.

1. Ce este o Matrice? “O Tablă de Șah cu Numere”

Gândește-te la o matrice ca la o foaie de matematica împărțită în căsuțe: fiecare căsuță are o adresă (rând, coloană) și poate conține o valoare.

Definiția Matricei:
O matrice este un vector de vectori – un tablou bidimensional cu rânduri și coloane.

Analogie cu o Clasă de Școală:

Fără matrice: “Elevul 1, randul 1, scaunul 1”, “Elevul 2, randul 1, scaunul 2″…

Cu matrice: clasa[rand][scaun]

  • clasa[0][0] = randul 1, scaunul 1 (Popescu)
  • clasa[0][1] = randul 1, scaunul 2 (Ionescu)
  • clasa[1][0] = randul 2, scaunul 1 (Georgescu)

2. Cum se Declară o Matrice? “Desenăm Tabloul”

#include <iostream>
using namespace std;

int main() {
    // METODA 1: Matrice cu dimensiuni fixe
    int matrice[3][4];  // 3 rânduri, 4 coloane

    // METODA 2: Matrice cu inițializare directă
    int tabla[2][3] = {
        {1, 2, 3},   // Randul 0
        {4, 5, 6}    // Randul 1
    };

    // METODA 3: Matrice pătratică (număr egal de rânduri și coloane)
    int patrat[3][3] = {
        {1, 0, 0},
        {0, 1, 0},
        {0, 0, 1}
    };

    // METODA 4: Lăsăm compilatorul să numere rândurile
    int autoMatrice[][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };  // Compilatorul înțelege că sunt 3 rânduri

    return 0;
}

3. Cum se Accesează Elementele? “Citesc de pe Tablă”

CHEIE IMPORTANTĂ: Indicele începe de la 0 pentru ambele dimensiuni!

#include <iostream>
using namespace std;

int main() {
    int matrice[2][3] = {
        {10, 20, 30},  // Randul 0
        {40, 50, 60}   // Randul 1
    };

    cout << "=== ACCESARE ELEMENTE MATRICE ===\n\n";

    // Accesare element individual
    cout << "Elementul de pe randul 0, coloana 1: " << matrice[0][1] << endl;  // 20
    cout << "Elementul de pe randul 1, coloana 2: " << matrice[1][2] << endl;  // 60

    // Modificare element
    matrice[0][1] = 99;  // Schimbă 20 în 99
    cout << "\nDupa modificare, matrice[0][1] = " << matrice[0][1] << endl;

    // Calcul cu elemente
    int suma = matrice[0][0] + matrice[1][2];  // 10 + 60 = 70
    cout << "Suma primului si ultimului element: " << suma << endl;

    return 0;
}

Imaginează-ți matricea astfel:

        Coloana 0   Coloana 1   Coloana 2
Randul 0:    10          20          30
Randul 1:    40          50          60

matrice[rand][coloana]

4. Cum se Parcurg Matricile? “Plimbare prin Toate Căsuțele”

#include <iostream>
using namespace std;

int main() {
    int matrice[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    cout << "=== PARCURGERE MATRICE ===\n\n";

    // Parcurgere completă - două bucle for imbricate
    for(int rand = 0; rand < 3; rand++) {        // Pentru fiecare rând
        for(int coloana = 0; coloana < 4; coloana++) {  // Pentru fiecare coloană
            cout << matrice[rand][coloana] << "\t";  // Afișează elementul
        }
        cout << endl;  // Linie nouă după fiecare rând
    }

    return 0;
}

Ce se întâmplă în spate:

Prima iterație: rand=0, coloana=0 → matrice[0][0] = 1
A doua iterație: rand=0, coloana=1 → matrice[0][1] = 2
...
Când termină coloanele pentru rand=0, trece la rand=1

5. Cum se Citesc Matricile de la Tastatură? “Umplem Tabloul”

#include <iostream>
using namespace std;

int main() {
    const int RANDURI = 3;
    const int COLOANE = 3;
    int matrice[RANDURI][COLOANE];

    cout << "=== CITIRE MATRICE DE LA TASTATURA ===\n\n";

    // Citire element cu element
    for(int rand = 0; rand < RANDURI; rand++) {
        cout << "Randul " << rand + 1 << ":\n";

        for(int coloana = 0; coloana < COLOANE; coloana++) {
            cout << "  Coloana " << coloana + 1 << ": ";
            cin >> matrice[rand][coloana];
        }
    }

    // Afișare pentru verificare
    cout << "\nMatricea introdusa este:\n";
    for(int rand = 0; rand < RANDURI; rand++) {
        for(int coloana = 0; coloana < COLOANE; coloana++) {
            cout << matrice[rand][coloana] << " ";
        }
        cout << endl;
    }

    return 0;
}

Varianta mai compactă:

#include <iostream>
using namespace std;

int main() {
    int matrice[2][3];

    cout << "Introdu 6 numere (2 randuri × 3 coloane):\n";

    // Citire compactă
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 3; j++) {
            cin >> matrice[i][j];
        }
    }

    return 0;
}

6. Operații Esentiale cu Matrici

6.1 Suma elementelor unei matrice

#include <iostream>
using namespace std;

int main() {
    int matrice[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    int suma = 0;

    // Parcurge și adună toate elementele
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            suma += matrice[i][j];
        }
    }

    cout << "Suma tuturor elementelor: " << suma << endl;  // 1+2+...+9 = 45

    return 0;
}

6.2 Găsirea elementului maxim

#include <iostream>
using namespace std;

int main() {
    int matrice[2][4] = {
        {15, 23, 8, 41},
        {7, 32, 19, 5}
    };

    // Presupunem că primul element e maxim
    int maxim = matrice[0][0];
    int randMax = 0, coloanaMax = 0;

    // Caută un element mai mare
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 4; j++) {
            if(matrice[i][j] > maxim) {
                maxim = matrice[i][j];
                randMax = i;
                coloanaMax = j;
            }
        }
    }

    cout << "Elementul maxim este " << maxim 
         << " la pozitia [" << randMax << "][" << coloanaMax << "]" << endl;

    return 0;
}

6.3 Suma pe fiecare rând

#include <iostream>
using namespace std;

int main() {
    int matrice[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    cout << "Suma pe fiecare rand:\n";

    for(int rand = 0; rand < 3; rand++) {
        int sumaRand = 0;

        for(int coloana = 0; coloana < 3; coloana++) {
            sumaRand += matrice[rand][coloana];
        }

        cout << "Randul " << rand << ": " << sumaRand << endl;
    }

    return 0;
}

6.4 Suma pe fiecare coloană

#include <iostream>
using namespace std;

int main() {
    int matrice[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    cout << "Suma pe fiecare coloana:\n";

    for(int coloana = 0; coloana < 3; coloana++) {
        int sumaColoana = 0;

        for(int rand = 0; rand < 3; rand++) {
            sumaColoana += matrice[rand][coloana];
        }

        cout << "Coloana " << coloana << ": " << sumaColoana << endl;
    }

    return 0;
}

7. Matricea Transpusă: “Întoarcerea pe Dos”

Transpusa unei matrice se obține schimbând rândurile cu coloanele.

#include <iostream>
using namespace std;

int main() {
    int matrice[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };

    cout << "Matricea originala (2x3):\n";
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 3; j++) {
            cout << matrice[i][j] << " ";
        }
        cout << endl;
    }

    // Matricea transpusă va fi 3x2
    int transpusa[3][2];

    // Construim transpusa
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 3; j++) {
            transpusa[j][i] = matrice[i][j];  // Schimbă indicii!
        }
    }

    cout << "\nMatricea transpusa (3x2):\n";
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 2; j++) {
            cout << transpusa[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

Ce se întâmplă:

Originala:    Transpusa:
1 2 3         1 4
4 5 6         2 5
              3 6

8. Matrice Pătratică: “Când Rândurile = Coloanele”

#include <iostream>
using namespace std;

int main() {
    // Matrice pătratică 4x4
    int patrat[4][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12},
        {13, 14, 15, 16}
    };

    cout << "=== OPERATII CU MATRICE PATRATICA ===\n\n";

    // 1. Diagonala principală (de la stânga-sus la dreapta-jos)
    cout << "Diagonala principala: ";
    for(int i = 0; i < 4; i++) {
        cout << patrat[i][i] << " ";  // i == j
    }
    cout << endl;

    // 2. Diagonala secundară (de la dreapta-sus la stânga-jos)
    cout << "Diagonala secundara: ";
    for(int i = 0; i < 4; i++) {
        cout << patrat[i][3 - i] << " ";  // i + j = n-1
    }
    cout << endl;

    // 3. Elemente de deasupra diagonalei principale
    cout << "\nElemente de deasupra diagonalei principale:\n";
    for(int i = 0; i < 4; i++) {
        for(int j = i + 1; j < 4; j++) {  // j > i
            cout << patrat[i][j] << " ";
        }
    }
    cout << endl;

    // 4. Elemente de sub diagonala principală
    cout << "\nElemente de sub diagonala principala:\n";
    for(int i = 1; i < 4; i++) {          // i > 0
        for(int j = 0; j < i; j++) {      // j < i
            cout << patrat[i][j] << " ";
        }
    }

    return 0;
}

9. Aplicații Practice Simple

Aplicația 1: Nota elevilor la mai multe materii

#include <iostream>
using namespace std;

int main() {
    // 5 elevi, 4 materii
    double note[5][4];  // [elev][materie]

    cout << "=== SISTEM DE NOTE ===\n\n";

    // Citire note
    for(int elev = 0; elev < 5; elev++) {
        cout << "Elevul " << elev + 1 << ":\n";

        for(int materie = 0; materie < 4; materie++) {
            cout << "  Materia " << materie + 1 << ": ";
            cin >> note[elev][materie];
        }
    }

    // Calcul medii elevi
    cout << "\n=== MEDII ELEVI ===\n";
    for(int elev = 0; elev < 5; elev++) {
        double suma = 0;

        for(int materie = 0; materie < 4; materie++) {
            suma += note[elev][materie];
        }

        double medie = suma / 4;
        cout << "Elevul " << elev + 1 << ": " << medie << endl;
    }

    // Calcul medii pe materii
    cout << "\n=== MEDII MATERII ===\n";
    for(int materie = 0; materie < 4; materie++) {
        double suma = 0;

        for(int elev = 0; elev < 5; elev++) {
            suma += note[elev][materie];
        }

        double medie = suma / 5;
        cout << "Materia " << materie + 1 << ": " << medie << endl;
    }

    return 0;
}

Aplicația 2: Tabla înmulțirii

#include <iostream>
using namespace std;

int main() {
    int tabla[10][10];  // 10x10

    // Generează tabla înmulțirii
    for(int i = 0; i < 10; i++) {
        for(int j = 0; j < 10; j++) {
            tabla[i][j] = (i + 1) * (j + 1);
        }
    }

    // Afișează tabla
    cout << "=== TABLA INMULTIRII (1-10) ===\n\n";
    cout << "   ";  // Colțul stânga-sus

    // Antet coloane
    for(int j = 0; j < 10; j++) {
        cout << j + 1 << "\t";
    }
    cout << "\n   -----------------------------------------\n";

    // Conținut tabla
    for(int i = 0; i < 10; i++) {
        cout << i + 1 << "| ";  // Antet rânduri

        for(int j = 0; j < 10; j++) {
            cout << tabla[i][j] << "\t";
        }
        cout << endl;
    }

    return 0;
}

10. Parcurgeri Speciale

10.1 Parcurgere pe coloane

#include <iostream>
using namespace std;

int main() {
    int matrice[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    cout << "Parcurgere pe coloane (mai intai coloana, apoi randul):\n";

    for(int coloana = 0; coloana < 3; coloana++) {
        for(int rand = 0; rand < 3; rand++) {
            cout << matrice[rand][coloana] << " ";
        }
        cout << endl;
    }

    return 0;
}

10.2 Parcurgere în spirală (concept)

Imaginează-ți că mergi în spirală:
1. Mergi pe primul rând de la stânga la dreapta
2. Mergi pe ultima coloană de sus în jos  
3. Mergi pe ultimul rând de la dreapta la stânga
4. Mergi pe prima coloană de jos în sus
5. Repetă pentru interior

11. Cum Păstrăm Dimensiunile Matricei?

#include <iostream>
using namespace std;

int main() {
    // Folosim constante pentru claritate
    const int RANDURI = 3;
    const int COLOANE = 4;

    int matrice[RANDURI][COLOANE];

    // Folosim constantele peste tot
    for(int i = 0; i < RANDURI; i++) {
        for(int j = 0; j < COLOANE; j++) {
            matrice[i][j] = i * j;
        }
    }

    // Dacă vrem să afișăm dimensiunile
    cout << "Matricea are " << RANDURI << " randuri si " 
         << COLOANE << " coloane\n";

    return 0;
}

12. Matrici de Caractere (Tablouri de String-uri)

#include <iostream>
using namespace std;

int main() {
    // Matrice de caractere - ca un vector de string-uri
    char cuvinte[3][10] = {  // 3 cuvinte, maxim 9 caractere + terminator
        "calculator",
        "programare", 
        "algoritm"
    };

    cout << "Cuvintele noastre:\n";
    for(int i = 0; i < 3; i++) {
        cout << i + 1 << ". " << cuvinte[i] << endl;
    }

    // Matrice pentru X si O (joc X si 0)
    char tabla[3][3] = {
        {'X', 'O', 'X'},
        {'O', 'X', 'O'},
        {'X', 'O', 'X'}
    };

    cout << "\nTabla de X si 0:\n";
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            cout << tabla[i][j] << " ";
        }
        cout << endl;
    }

    return 0;
}

13. Greșeli Comune și Cum Să Le Evităm

#include <iostream>
using namespace std;

int main() {
    int matrice[2][3];

    cout << "=== ATENTIE LA GRESELI COMUNE ===\n\n";

    // 1. Accesare în afara limitelor
    // matrice[2][3] = 5;  // GRESIT! Matricea e 2x3, deci indicii merg 0-1 și 0-2

    // 2. Amestecarea rândurilor cu coloanele
    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};

    cout << "a[0][2] = " << a[0][2] << endl;  // Corect: 3
    cout << "a[2][0] = " << "GRESIT! Matricea are doar 2 randuri (0-1)\n";

    // 3. Uitarea că indicii încep de la 0
    cout << "\nPrimul element e a[0][0], nu a[1][1]!\n";
    cout << "Ultimul element e a[1][2], nu a[2][3]!\n";

    // 4. Parcurgere greșită
    cout << "\nParcurgere corecta (doua bucle):\n";
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 3; j++) {
            cout << a[i][j] << " ";
        }
    }

    return 0;
}

14. EXERCIȚII Practice de Înțelegere

Exercițiul 1: Completează codul

#include <iostream>
using namespace std;

int main() {
    int matrice[2][3] = {
        {5, 8, 3},
        {2, 7, 4}
    };

    // TODO: Calculează suma elementelor
    int suma = 0;
    // Scrie codul aici

    cout << "Suma elementelor: " << suma << endl;

    // TODO: Găsește elementul minim
    int minim = matrice[0][0];
    // Scrie codul aici

    cout << "Elementul minim: " << minim << endl;

    return 0;
}

Soluție:

// Pentru suma:
for(int i = 0; i < 2; i++) {
    for(int j = 0; j < 3; j++) {
        suma += matrice[i][j];
    }
}

// Pentru minim:
for(int i = 0; i < 2; i++) {
    for(int j = 0; j < 3; j++) {
        if(matrice[i][j] < minim) {
            minim = matrice[i][j];
        }
    }
}

Exercițiul 2: Întrebări rapide

  1. Cum accesezi elementul din colțul dreapta-jos al unei matrice 4×5?
  2. Cum parcurgi doar elementele de pe prima coloană?
  3. Ce face matrice[i][j] = i + j?

Răspunsuri:

  1. matrice[3][4] (pentru că indicii încep de la 0)
  2. for(int i = 0; i < numarRanduri; i++) cout << matrice[i][0];
  3. Completează matricea cu suma indicilor

În concluzie, să-ți spun ceva fundamental:

Matricile nu sunt doar un concept abstract de matematică – sunt modul în care calculatorul vede tabelele, imaginile (pixeli), hărțile, orice are rânduri și coloane. O matrice e ca o fotografie digitală: fiecare pixel are coordonatele lui (rând, coloană) și o valoare (culoare).

Dar tratarea matricelor ca simple colecții de numere fără a înțelege structura lor bidimensională poate fi, paradoxal, o sursă de confuzie când încerci să rezolvi probleme spațiale sau de poziționare.

Așa că ai grijă când lucrezi cu matrici. Cunoștințe-ti coordonatele: unde ești? Ce înseamnă rândul 0? Ce înseamnă coloana 0? Pentru că puterea de a organiza datele pe două dimensiuni este goală fără înțelegerea sistemului de coordonate. Și această putere vine cu o responsabilitate: să fii precis cu indicii.

Stăpânirea matricelor este cheia pentru multe domenii avansate: grafică pe calculator, inteligenta artificiala, procesare de imagini. Ai grijă de ea cu aceeași seriozitate.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *