Contact și feedback

Nu obții 100 de puncte sau ai nelămuriri în privința problemelor? Scrie-mi pe Instagram.


Ai găsit o greșeală, vrei să raportezi un utilizator sau vrei să comunici altceva? Folosește formularul de contact.


Vrei să ne transmiți o părere despre platformă? Folosește formularul de feedback.

Shortcuturi

Folosește următoarele shortcuturi pentru a naviga mai ușor pe platformă.

Generale

Meniu shortcuturi?
Căutare probleme sau utilizatori/
Navigare printre rezultatele căutării↑, ↓
Meniu de contact și feedbackCTRL + Shift + F
Ieșire din meniuriEsc

Editor probleme

Setări editorCTRL + Shift + S
Schimbare stil editorCTRL + Shift + E
Șabloane de codCTRL + Shift + 1/2/3
Golire editorCTRL + Shift + 4

Matrice în C++. Declararea și parcurgerea tablourilor bidimensionale

Am învățat până acum să lucrăm cu variabile individuale, sau chiar să lucrăm cu vectori — în care stocăm un număr de variabile de același tip, într-o linie.

În C++, matricele extind vectorii în 2D — de unde vine și numele de tablou bidimensional. Mai exact, într-o matrice, elementele sunt organizate pe linii și pe coloane.

Spre exemplu, iată o matrice de dimensiuni 3 × 4:

Dă hover pe un element pentru a-i găsi linia și coloana.

Ne reamintim că la vectori, puteam să luăm câte un element folosind indicele său — practic folosind poziția din vector. La matrici, ne vom folosi de 2 indici: unul care numește linia, și celălalt care numește coloana elementului curent.

Declararea matricelor în C++

Declararea unei matrice constă în specificarea celor două dimensiuni: numărul maxim de linii și numărul maxim de coloane.

tip nume[numarLinii][numarColoane];

Spre exemlu, o matrice de numere cu 3 linii și 4 coloane se declară astfel:

int a[3][4];

Și poate fi reprezentată așa (elementele sunt alese aleatoriu):

https://i.ibb.co/TWKGsH2/image.png

Observații

Observăm următoarele lucruri:

  • Matricea de mai sus are 3 * 4 = 12 elemente; o matrice cu n linii și m coloane are n * m elemente;
  • Practic, o matrice este un vector de vectori;
  • Liniile sunt indexate (numerotate) de la 0 la 2. Coloanele sunt indexate de la 0 la 3; cu toate acestea, ca la vectori, putem să numerotăm indicii de la 1 în loc de 0, nelucrând cu elementele de pe linia/coloana 0.
  • Liniile sunt de sus în jos, iar coloanele sunt de la stânga la dreapta;
  • Memoria unei matrici crește exponențial: o matrice 1000 * 1000 este de 100 de ori mai mare decât una de 100 * 100.

Cum se salvează matricele în memorie

Ca un fun fact pentru cei interesați, cum în memorie nu există noțiunea de 2D (adică toate informațiile din memorie sunt consecutive, una după alta), o matrice cu n linii și m coloane se salvează ca o înșiruire de n * m elemente. Așadar, în anumite medii de programare, apelând elementul de pe linia 0, coloana m, o să obținem elementul de pe linia 1, coloana 0 (deoarece matricea are coloane de la 0 la m - 1, coloana m este practic următorul element, adică de pe linia următoare și coloana 0).

Spre exemplu, matricea de mai sus se reprezintă în memorie astfel: 1, 3, 6, 2, 2, 4, 12, 44, 0, 3, 5, 7.

Accesarea elementelor din matrice

Cum probabil ați intuit, pentru accesarea elementului de pe linia i și coloana j a unei matrici a, apelăm a[i][j]. Spre exemplu, în matricea de mai sus, a[0][2] = 6.

Parcurgerea unei matrice în C++

Parcurgerea unei matrice poate părea un pic mai greu de înțeles. Când vorbim de parcurgerea unei matrice, vrem să parcurgem elementele sale linie cu linie, de sus în jos și de la stânga la dreapta — exact cum se afișează pixelii pe un televizor:

Secvență preluată de la The Slo Mo Guys

(Secvență preluată de la The Slow Mo Guys)

Pentru a face acest lucru, vom folosi două structuri repetitive for imbricate (una în alta): prima după i, iar a doua după j. Cea din afară (după i) va parcurge, pe rând, liniile matricei, de la 0 la n - 1. Pentru fiecare linie în parte, vom parcurge elementele de la stânga la dreapta (de la 0 la m - 1) folosind al doilea for (care este după j). Astfel, reușim să parcurgem toate elementele matricei cu ușurință.

Indexare de la 0

#include <iostream>

using namespace std;

int n, m, a[101][101]; //n = nr linii, m = nr coloane, a = matricea

int main()
{
    cin >> n >> m; //Citim numărul de linii și de coloane

    //Parcurgem matricea exact cum am explicat anterior
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            a[i][j] = 1;
        }
    }
    return 0;
}

Indexare de la 1

Indexarea de la 1 înseamnă să numerotăm elementele matricei de la 1 la n și de la 1 la m, în loc să numerotăm de la 0 la n - 1 și de la 0 la m - 1. De multe ori se preferă indexarea de la 1 (vom vedea mai târziu de ce), dar din această cauză vom folosi indexarea de la 1 de acum înainte. Să vedem cum se parcurge o matrice indexată de la 1:

#include <iostream>

using namespace std;

int n, m, a[101][101]; //n = nr linii, m = nr coloane, a = matricea

int main()
{
    cin >> n >> m; //Citim numărul de linii și de coloane

    //Parcurgem matricea exact cum am explicat anterior
    for(int i = 1; i <= n; i++) { //1 - n
        for(int j = 1; j <= m; j++) { //1 - m
            a[i][j] = 1;
        }
    }
    return 0;
}

Citirea și afișarea unei matrici

Citirea unui tablou bidimensional

Citirea matricei folosește parcurgerea de mai devreme pentru a lua elementele pe rând și a le citi de la tastatură. Iată un exemplu:

cin >> n >> m; //Citim dimensiunile matricei

//Citim matricea, parcurgem cum am învățat anterior
for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
        cin >> a[i][j];

Afișarea unui tablou bidimensional

Afișarea unui tablou este similară, însă după ce afișăm fiecare linie în parte, trebuie să afișăm un endl pentru a trece la următoarea linie.

//Afișăm matricea, parcurgem cum am învățat anterior
for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= m; j++)
        cout << a[i][j] << " ";
    cout << endl;
}

Exemplu

Iată un cod în C++ care citește de la tastatură o matrice și o afișează pe ecran:

#include <iostream>

using namespace std;

int n, m, a[101][101]; //n = nr linii, m = nr coloane, a = matricea

int main()
{
    cin >> n >> m; //Citim numărul de linii și de coloane

    //Citim matricea
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }

    //Afișăm matricea
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            cout << a[i][j] << " ";
        }
        cout << "\n";
    }
    return 0;
}

Matrici pătratice

Pentru lecția completă a matricelor pătratice, intră pe această pagină.

Ce este o matrice pătratică?

O matrice pătratică este o matrice particulară, cu același număr de linii și de coloane — adică cu n == m. Pentru simplitate, vom menționa doar n-ul, deoarece m-ul are aceeași valoare. Matricea de acest tip are o serie de particularități care se folosesc în anumite probleme.

Diagonala principală și diagonala secundară

Diagonala principală a unei matrice este diagonala care începe din colțul stânga-sus și se termină în colțul dreapta-jos. Mai exact, un element a[i][j] aparține diagonalei principale dacă i == j.

Similar, diagonala secundară este cealaltă diagonală, care începe din colțul dreapta-sus și se termină în cel stânga-jos. Un element a[i][j] aparține diagonalei secundare dacă i + j == n + 1, sau cu alte cuvinte, j == n - i + 1 (unde matricea este indexată de la 1).

În imaginea de mai jos, diagonala principală este cea roșie, diagonala secundară este cea albastră, elementul 4 (din mijloc) aparținând ambelor diagonale.

https://i.ibb.co/1qvhPpb/image.png

Exerciții propuse

Completează următoarea secvență de cod:

Să se atribuie fiecărui element din matrice produsul indicilor săi:

for(int i = 1; i <= n; i++) {
    for(int j = 1; j <= m; j++) {
        a[i][j] = i * ???;
    }
}

Care este cea mai mică dimensiune pe care o poate lua matricea astfel încât codul să funcționeze cum trebuie?

int a[3][???];
for(int i = 1; i <= 2; i++) {
    for(int j = 1; j <= 3; j++) {
        a[i][j] = 1;
    }
}

Probleme propuse

# Problemă Dificultate
633. Livada Ușoară (2 )
692. Fibosnek Grea (8 )
132. Suma valorilor impare din matrice Ușoară (2 )
149. Izolare Ușoară (2 )
137. Permutare in matrice Ușoară (2 )
Vrei mai multe probleme? Pe această pagină găsești întreaga listă de probleme propuse.

Alte resurse sau bibliografie

Obține medalia mult dorită. Devino As la olimpiadă.

Curs complet de olimpiadă, pregătit de olimpici de la Oxford și TU Delft.

Cuprinsul lecției

Se încarcă…

Citește și

Instrucțiunea break (structuri repetitive)Verificare dacă un număr este palindrom în C++Verifică dacă un caracter este cifră în C++Ce înseamnă variabilă globală și locală în C++?Bordarea unei matrice în C++Codul ASCII (tabel complet)Cum să afișezi partea întreagă a unui număr real în C++Suma 1 + 2 + 3 + ... + N în C++Verifică dacă o literă este mică sau mare în C++Numărul aranjamentelor în C++ (formula aranjamentelor)Numărul combinărilor în C++ (formula combinărilor)Maximul și minimul unui vector în C++Transformarea unei litere mici în literă mare în C++Funcții în C++. Ce sunt subprogrameleCMMDC recursiv a două numere naturale în C++Verifică dacă o literă este vocală în C++Oglinditul recursiv al unui număr în C++Calculul combinărilor de n luate câte k (nCk) în C++Numărul de divizori al numerelor de la 1 la N (Folosind ciurul lui Eratostene)Verifică dacă un număr este par sau impar fără modulo în C++Afișarea divizorilor primi ai unui număr în C++Combinatorică în C++: permutări, aranjamente, combinări și alteleAl N-lea termen dintr-o progresie aritmeticăNumărul de apariții al unui număr într-un vector în C++Verificare număr prim în C++ (Clasa a IX-a)Numărul minim de peroane pentru o gară în C++Ce este o variabilă unsigned în C++?Află secolul unui an citit de la tastatură în C++Tipuri de date în C++: numere întregi, reale, caractere și alteleDistanța dintre două puncte în C++Ce este o funcție void în C++?Matrice Fibonacci - al n-lea termen Fibonacci în timp logaritmicRădăcina cubică a unui număr în C++ (cube root)Cel mai puțin semnificativ bit în C++Numere triunghiulare. Verificarea unui număr triunghiularMaximul și minimul a două valori în C++Cel mai mare divizor comun (CMMDC) a două numere în C++Materia pentru olimpiada de informatică - tot ce trebuie să știiDo while vs while în C++ - Care e diferența?Valoarea absolută (modulul) unui număr în C++Copiuțe: Cifrele unui numărSuma divizorilor numerelor de la 1 la N (Folosind ciurul lui Eratostene)Instrucțiunea continue (structuri repetitive)Verifică dacă un număr dat este o putere de 2 în C++Verifică dacă un caracter este literă în C++Transformarea unei litere mari în literă mică în C++Cifrele unui număr. Prelucrarea cifrelor unui număr în C++Verificare dacă șir de caractere este palindrom în C++Instrucțiunea de decizie în C++: if, else, switch, caseRecursivitate în C++Verifică dacă trei puncte sunt coliniare C++Maximul și minimul a n valori în C++Cel mai semnificativ bit în C++Afișarea elementelor unui vector recursiv în C++Cea mai lungă secvență de elemente crescătoare în C++Inversarea unui vector în C++Factorialul unui număr în C++Numărul de divizori primi ai unui număr în C++Matrice pătratice în C++. Diagonala principală și secundarăCiurul lui Eratostene în C++Operații cu numere mari în C++ - Toate funcțiile explicateAl N-lea termen Fibonacci în C++Citește un șir de caractere cu spații în C++Cel mai mic/mare divizor prim al numerelor de la 1 la N (Folosind ciurul lui Eratostene)Pointer în C++. Variabile de tipul char * (char steluță)Structuri repetitive (while, do while, for, etc)Cifra maximă și minimă a unui număr în C++Căutare binară în C++Vectorii în C++: citire și afișareTransformarea unui număr din baza 2 în baza 10 în C++Cum să calculezi instant 2 la puterea N în C++Sortare crescătoare recursivă în C++ - Merge sort și Bubble sortComplexitatea unui algoritm (timp și spațiu) în C++Ridicarea la putere în timp logaritmic în C++. Exponențiere rapidăOglinditul unui număr în C++Indicatorul lui Euler al numerelor de la 1 la N (Folosind ciurul lui Eratostene)Șirul lui Fibonacci în C++Vectori de frecvență (de apariții) în C++Tutorial instalare CodeBlocks (ușor) - Introducere în informatică C++Inversarea unui șir de caractere în C++Instrucțiunea while (structuri repetitive)Generarea șirului Fibonacci generalizat în C++Funcții predefinite în C++ (matematice, șiruri de caractere)Aria și circumferința unui cerc în C++Aflarea sumei primelor N sume GaussȘiruri de caractere în C++. Tot ce trebuie să știiDe ce cer unele probleme răspunsul modulo 666013 sau modulo 1.000.000.007?Aplicații cu ciurul lui Eratostene în C++: suma divizorilor, numărul divizorilorInterschimbarea a două variabile în C++ (3 metode)Suma elementelor unui vector recursiv în C++Prima cifră a unui număr în C++Matrice în C++. Declararea și parcurgerea tablourilor bidimensionaleInstrucțiunea do while (structuri repetitive)Divide et Impera (metodă de programare C++)Numărul de divizori al unui număr în C++Aria unui triunghi folosind coordonatele acestora în C++Ce înseamnă endl în C++?Suma divizorilor unui număr în C++Citirea și afișarea matricelor în C++Algoritm recursiv pentru căutare binară (clasa a X-a)Cum să citești și să afișezi în fișiere în C++Numărul permutărilor în C++ (formula permutărilor)Instrucțiunea for (structuri repetitive)Verifică dacă un bit de pe o anumită poziție este 1 sau 0 în C++Tipul struct în C++. Ce sunt structurile de date neomogeneMaximul și minimul a trei valori în C++Cifra maximă a unui număr recursiv în C++Câte numere naturale sunt într-un interval dat? (C++)Interclasarea a doi vectori în C++Vectorii în C++: declarare și parcurgereCMMMC a două numere în C++ (cel mai mic multiplu comun)Comentarii în C++Radicalul unui număr în C++ (rădăcina pătrată)Mediana unui șir de valori în C++Al N-lea termen dintr-o progresie geometricăVerifică dacă un număr aparține șirului Fibonacci în C++Cel mai mic număr cu suma cifrelor N în C++Cifra de control a unui numărVerificarea unui an bisect în C++Indicatorul lui Euler în C++Transformarea unui număr din baza 10 în baza 2 în C++Suma numerelor naturale dintr-un interval dat în C++Cel mai frecvent element dintr-un șir în C++Numărul de cifre ale factorialului unui număr

© Drepturi de autor

Echipa InfoAs își rezervă drepturile de autor pentru conținutul acestei pagini. Copierea conținutului fără acordul scris expres al InfoAs reprezintă o încălcare a Legii 8/1996 și va fi tratată ca atare.

Trimite lecția

Toată lecția

Doar videoclipul pe YouTube

Informatica devine ușoară cu InfoAs

Intră în cont