Pagina Modulului 4
Ora 17 - Modulul 4

Ce este un vector?

Învață conceptele de bază ale vectorilor: declarare, indexare, citire și afișare

40min teorie + 15min probleme PbInfo
Competența 4.1
Săptămâna 1
Sigla liceului
TEORIE - 40 minute

Ce vei învăța astăzi?

După această lecție, vei înțelege conceptul de vector și vei putea declara, citi și afișa vectori în C++.

Analogii simple pentru vectori
Declararea vectorilor în C++
Indexarea de la 0 (foarte important!)
Citirea și afișarea unui vector

Ce este un vector?

Definiție: Un vector (array) este o colecție ordonată de elemente de același tip, stocate în memorie una lângă alta.

Exemplu: Dacă avem 5 note de elev, le putem stoca într-un vector note[5].

note[0]
9
note[1]
8
note[2]
10
note[3]
7
note[4]
9
5 elemente
Dimensiunea vectorului
note[0] ... note[4]
Indici de la 0 la 4
int note[5]
Declarare în C++

Analogii pentru a înțelege vectorii:

Raft de cărți

Fiecare cărțuță este numerotată (0, 1, 2...). Poți lua cartea de pe poziția 3 fără să te uiți la celelalte.

Cutii poștale

Fiecare cutie are un număr. Poți pune sau lua scrisori doar din cutia cu numărul pe care îl știi.

Listă de cumpărături

Produsele sunt în ordine pe listă. Poți să te uiți la al treilea produs fără să parcurgi primele două.

Hotel cu camere

Camerele sunt numerotate (101, 102...). Poți merge direct la camera 105 fără să verifici camerele anterioare.

Declararea vectorilor în C++

// SINTAXA DE BAZĂ PENTRU DECLARARE VECTOR tip nume[dimensiune]; // EXEMPLE: int note[5]; // Vector de 5 numere întregi float temperaturi[7]; // Vector de 7 numere reale char litere[10]; // Vector de 10 caractere bool raspunsuri[20]; // Vector de 20 valori booleene // ATENȚIE! Dimensiunea trebuie să fie constantă const int N = 100; int vector[N]; // Corect - N este constant

Regula de aur: Indicele primului element este întotdeauna 0, nu 1! Ultimul element are indicele dimensiune-1.

Exemplu: Note elev
int note[5];  // 5 note pentru un elev
note[0] = 9;  // Prima notă
note[1] = 8;  // A doua notă
note[2] = 10; // A treia notă
note[3] = 7;  // A patra notă  
note[4] = 9;  // A cincea notă
Exemplu: Temperaturi
float temp[7];  // Temperaturi pentru 7 zile
temp[0] = 22.5; // Luni
temp[1] = 23.1; // Marți
temp[2] = 21.8; // Miercuri
// ... până la temp[6] - Duminică
// METODE DE INITIALIZARE A VECTORILOR // 1. Initializare directă (la declarare) int numere[5] = {10, 20, 30, 40, 50}; // 2. Initializare parțială (restul devin 0) int vector[10] = {1, 2, 3}; // primele 3 elemente, restul 0 // 3. Fără specificare dimensiune (compilatorul calculează) int zile[] = {1, 2, 3, 4, 5, 6, 7}; // dimensiune = 7 // 4. Toate elementele cu aceeași valoare int zero[100] = {0}; // toate elementele devin 0 // ATENȚIE! Nu poți face: // int note[5]; // note = {9, 8, 10, 7, 9}; // ❌ GRESIT!

Important: Initializarea directă se face doar la declarare. Dacă vrei să schimbi valorile mai târziu, trebuie să atribui fiecare element individual.

numere[0]
10
numere[1]
20
numere[2]
30
numere[3]
40
numere[4]
50

int numere[5] = {10, 20, 30, 40, 50};

Situație Declarare corectă Declarare greșită Explicație
5 numere întregi int v[5]; int v[5.5]; Dimensiunea trebuie să fie număr întreg
Initializare directă int v[] = {1,2,3}; int v[3]; v = {1,2,3}; Initializarea doar la declarare
Vector cu 0 int v[10] = {0}; int v[10] = 0; Folosește acolade pentru initializare
Dimensiune variabilă const int n=5; int v[n]; int n=5; int v[n]; Dimensiunea trebuie constantă

Sfaturi practice pentru începători:

  1. Folosește constante pentru dimensiuni: const int MAX = 100;
  2. Verifică întotdeauna că indicele este între 0 și dimensiune-1
  3. Nume descriptive pentru vectori: note, temperaturi, numeElevi
  4. Testează cu dimensiuni mici înainte să treci la dimensiuni mari

Modelul standard de parcurgere

Când ai un vector și vrei să lucrezi cu toate elementele lui, folosești aproape mereu aceeași idee: o buclă care pornește de la 0 și se oprește la n-1.

Asta înseamnă: primul element este v[0], iar ultimul este v[n-1].

Schema de bază
for (int i = 0; i < n; i++) {
    // aici lucrezi cu v[i]
}

Regula de aur: dacă ai dubii, scrie întâi bucla corectă. Apoi completezi ce trebuie în interior.

Ce vreau să fac Ce scriu în interiorul buclei
Afișez elementele cout << v[i] << " ";
Le citesc cin >> v[i];
Le dublez v[i] = v[i] * 2;
Număr câte sunt pare if (v[i] % 2 == 0) cnt++;

Ce înseamnă n și cum aleg dimensiunea

În probleme, n este de obicei câte valori citim. În C++ putem lucra în două moduri: fie folosim un tablou cu o dimensiune maximă, fie folosim un vector cu dimensiune exactă.

De ce putem scrie int v[MAX]; înainte de cin >> n;?

Pentru că MAX este o limită maximă (un „raft” cu multe locuri). Chiar dacă tu ai raft de 1000 locuri, nu înseamnă că îl umpli pe tot.

MAX

câte locuri are raftul (capacitatea)

n

câte locuri folosim azi (câte valori citim)

v[i]

valoarea de pe locul i (doar pentru i=0..n-1)

Regula practică: după ce ai citit n, lucrezi doar cu v[0], v[1], ..., v[n-1]. Restul locurilor există, dar nu te interesează.

Exemplu complet (clasic): „MAX + n”

Ce înseamnă În program
Stabilesc capacitatea maximă const int MAX = 1000;
Declar „raftul” int v[MAX];
Citesc câte valori am în problemă cin >> n;
Folosesc doar primele n locuri for(i=0;i<n;i++) cin>>v[i];
Cod (cu verificare simplă)
#include <iostream>
using namespace std;

int main() {
    const int MAX = 1000;
    int v[MAX];

    int n;
    cin >> n;

    if (n > MAX) {
        cout << "n prea mare (max " << MAX << ")\n";
        return 0;
    }

    for (int i = 0; i < n; i++) cin >> v[i];

    // aici lucrezi doar cu v[0..n-1]
    for (int i = 0; i < n; i++) cout << v[i] << " ";

    return 0;
}

Ideea-cheie: vectorul are MAX locuri, dar noi folosim doar n. Asta e tot.

A doua metodă: „vector care crește” (push_back)

Uneori vrei să construiești vectorul pas cu pas. Atunci folosești std::vector și adaugi elemente cu push_back.

Citesc n, apoi adaug pe rând în vector
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;

    vector<int> v;   // începe gol
    v.reserve(n);    // (opțional) rezerv loc pentru n elemente

    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        v.push_back(x);
    }

    for (int i = 0; i < (int)v.size(); i++) {
        cout << v[i] << " ";
    }

    return 0;
}
Metodă Când o folosesc Ce trebuie să știu
int v[MAX]; Probleme clasice, rapid și simplu n ≤ MAX, lucrezi cu v[0..n-1]
vector<int> v(n); Ai n din start și vrei dimensiune exactă Vectorul are deja n elemente: v[0..n-1]
vector<int> v; push_back Construiești treptat Dimensiunea e v.size()

Diferența de reținut: vector<int> v(n) creează n locuri, iar vector<int> v; începe gol și îl umpli cu push_back.

Varianta clasică (tablou cu dimensiune maximă)
const int MAX = 1000;
int v[MAX];

int n;
cin >> n;  // n trebuie să fie ≤ MAX
Varianta modernă (dimensiune exactă)
#include <vector>

int n;
cin >> n;
vector<int> v(n);

În modulul acesta puteți lucra fără probleme cu varianta clasică (MAX). Varianta modernă e un bonus util și o vom folosi din ce în ce mai des.

DE CE începem de la 0?

Regula fundamentală a indexării

În C++ (și majoritatea limbajelor de programare), vectorii încep de la indicele 0.

Analogie: Numărul etajelor la lift

Parter = etaj 0
Etaj 1 = de fapt etajul 2 din viața reală
La lift apăsăm "0" pentru parter, nu "1"!

Deci: indice = distanța de la începutul vectorului

Vector cu 5 elemente - cum funcționează indexarea:
Elementul 1: este la poziția 0 (0 pași de la început)
Elementul 2: este la poziția 1 (1 pas de la început)
Elementul 3: este la poziția 2 (2 pași de la început)
Elementul 4: este la poziția 3 (3 pași de la început)
Elementul 5: este la poziția 4 (4 pași de la început)

Cel mai frecvent bug la începători: Accesarea elementului v[5] într-un vector de 5 elemente. Corect este v[0] până la v[4]!

Exercițiu de completare - Declarare vector:

Completează codul C++ pentru declararea și utilizarea unui vector:
#include <iostream>
using namespace ______;
______ main() {
    // Declarăm un vector de 5 numere întregi
    ______ note______;
    // Citim cele 5 note
    for (______ i = ______; i < ______; i++) {
        cin >> note______;
    }
    // Afișăm notele în ordine inversă
    for (int i = ______; i >= ______; i______) {
        cout << note[i] << " ";
    }
    return ______;
}
Bancă de cuvinte:
std int [5] 0 5 [i] 4 --

Test de înțelegere: Care este valoarea corectă?

Test rapid - indexarea vectorilor:

Avem declararea: int v[5] = {10, 20, 30, 40, 50};

Vectorul în memorie:
v[0]
10
v[1]
20
v[2]
30
v[3]
40
v[4]
50

Care este valoarea lui v[3]?

Care este indicele ultimului element?

Sfaturi practice pentru lucrul cu vectori

Folosește întotdeauna constante pentru dimensiuni

const int MAX = 100; int v[MAX]; - este mai ușor de modificat și mai sigur.

Verifică întotdeauna limitele indexului

Accesarea v[5] într-un vector de 5 elemente (v[0]...v[4]) dă eroare!

Parcurge vectorul cu for de la 0 la n-1

for (int i = 0; i < n; i++) este modelul standard pentru parcurgere.

Nume descriptive pentru vectori

noteElevi este mai bun decât v sau arr.

Greșeli frecvente și corectarea lor

Greșit De ce? Corect
for (int i = 1; i <= n; i++) Indexarea începe de la 0 for (int i = 0; i < n; i++)
v[n] Ultimul element este la n-1 v[n-1]
int v[n]; n nu e constant la compilare const int MAX = 1000; int v[MAX];

Dacă îți iese „un element în plus” sau „lipsește primul element”, verifică imediat limita buclei: i < n, nu i <= n.

Capcane comune și soluții pentru vectori

Greșeli frecvente la lucrul cu vectori:

❌ Indexarea de la 1 în loc de 0
// GREȘIT int v[5]; for (int i = 1; i <= 5; i++) { // începe de la 1, merge până la 5 cin >> v[i]; // v[1], v[2], v[3], v[4], v[5] - v[5] nu există! } // CORECT for (int i = 0; i < 5; i++) { // începe de la 0, merge până la 4 cin >> v[i]; // v[0], v[1], v[2], v[3], v[4] }

Soluție: Întotdeauna începe de la 0 și folosește i < dimensiune.

❌ Dimensiune variabilă (în C++ standard)

În C++ standard, dimensiunea unui vector trebuie să fie constantă la compilare.

// GREȘIT int n; cin >> n; int v[n]; // nu este permis în C++ standard // CORECT const int MAX = 100; // dimensiune maximă int v[MAX]; int n; cin >> n; // n trebuie să fie ≤ MAX
❌ Initializare greșită după declarare

Nu poți folosi acolade pentru a atribui valori unui vector după declarare.

// GREȘIT int v[5]; v = {1, 2, 3, 4, 5}; // eroare de compilare! // CORECT int v[5] = {1, 2, 3, 4, 5}; // initializare la declarare // SAU int v[5]; for (int i = 0; i < 5; i++) { v[i] = i + 1; // atribuire individuală }

Best Practices pentru vectori:

✅ Folosește constante pentru dimensiuni - const int N = 100;
✅ Verifică limitele indexului - întotdeauna între 0 și n-1
✅ Folosește for cu 0-based indexing - for (int i = 0; i < n; i++)
✅ Nume descriptive - noteElevi nu v
✅ Initializează vectorii - fie la declarare, fie cu o buclă

Încălzire (2 minute)

Test rapid - declarații vectori: Care sunt corecte și care sunt greșite?

  • int vector[5];verifică
  • float temp[];verifică
  • char litere[10] = {'a', 'b', 'c'};verifică

Hint: vectorul trebuie să aibă dimensiune specificată (cu excepția cazului când este inițializat).

MINI-EXERCIȚII - 2-3 minute

Fără să scrii program complet, răspunde:

  1. Dacă n = 7, care este indicele ultimului element?
  2. Ce afișează: cout << v[0]; ?
  3. Ce indice are al treilea element (ca poziție) din vector?

Scopul este să nu mai existe confuzie între „al treilea element” și „indice 3”.

PROBLEME PBINFO - 15 minute

PbInfo #158 - Citire și afișare vector

Enunț:

Cerință: Se citește un număr n și apoi n numere naturale. Să se afișeze elementele vectorului în ordinea citirii.

Date de intrare:

Programul citește de la tastatură numărul n, apoi n numere naturale.

Date de ieșire:

Programul va afișa pe ecran cele n numere, separate prin spații.

Exemplu:

Intrare:

5
10 20 30 40 50

Ieșire:

10 20 30 40 50

Explicație: Vectorul este afișat exact în ordinea citirii

Cum gândim soluția:
  1. Citim numărul n (dimensiunea vectorului)
  2. Declarăm un vector cu dimensiunea n (sau cu dimensiune maximă)
  3. Citim cele n elemente într-o buclă for:
    • for (int i = 0; i < n; i++)
    • cin >> v[i];
  4. Afișăm elementele în aceeași ordine:
    • for (int i = 0; i < n; i++)
    • cout << v[i] << " ";
Execuție pentru n=3 cu valori 7, 8, 9:
Pas 1: Citim n=3
Pas 2: Declarăm vector v[3]
Pas 3: Citire: i=0 → v[0]=7
Pas 4: Citire: i=1 → v[1]=8
Pas 5: Citire: i=2 → v[2]=9
Pas 6: Afișare: 7 8 9 ✓
Ce trebuie să verifici mereu?
  • Dimensiunea vectorului să fie suficient de mare
  • Indicele să înceapă de la 0 și să se termine la n-1
  • Să nu uiți să afișezi spații între elemente
  • Să nu afișezi spațiu după ultimul element (dar PbInfo e tolerant)
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    // Declarăm vectorul cu dimensiune maximă 1000
    // (sau cu dimensiunea exactă n dacă folosim alocare dinamică mai târziu)
    const int MAX = 1000;
    int v[MAX];
    
    // Citim cele n elemente
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    
    // Afișăm elementele în ordinea citirii
    for (int i = 0; i < n; i++) {
        cout << v[i] << " ";
    }
    
    return 0;
}
Varianta cu dimensiune exactă (BONUS - std::vector):
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;

    vector<int> v(n); // dimensiune exactă

    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }

    for (int i = 0; i < n; i++) {
        cout << v[i] << " ";
    }

    return 0;
}

Ce învățăm din această problemă:

  • Citirea unui vector: folosind o buclă for de la 0 la n-1
  • Afișarea unui vector: aceeași structură ca la citire
  • Indexarea corectă: începând de la 0, până la n-1
  • Dimensiune vector: folosirea constantei MAX pentru siguranță
  • Spații la afișare: separator între elemente

PbInfo #159 - Afișare inversă a unui vector

Problemă care afișează elementele vectorului în ordine inversă

Enunț:

Cerință: Se citește un număr n și apoi n numere naturale. Să se afișeze elementele vectorului în ordine inversă față de ordinea citirii.

Date de intrare:

Programul citește de la tastatură numărul n, apoi n numere naturale.

Date de ieșire:

Programul va afișa pe ecran cele n numere în ordine inversă, separate prin spații.

Exemplu:

Intrare:

5
10 20 30 40 50

Ieșire:

50 40 30 20 10

Explicație: Elementele sunt afișate de la ultimul la primul

Cum gândim soluția:
  1. Citim n și cele n elemente (ca la problema anterioară)
  2. Pentru afișare inversă, parcurgem vectorul de la sfârșit la început:
    • Primul element afișat: v[n-1] (ultimul)
    • Ultimul element afișat: v[0] (primul)
    • Bucla: for (int i = n-1; i >= 0; i--)
  3. Atenție la condiția din buclă: i >= 0 (nu i > 0)
Cum funcționează pentru n=3 cu valori 7, 8, 9:
Vector: v[0]=7, v[1]=8, v[2]=9
Afișare inversă: i=2 → v[2]=9
Afișare inversă: i=1 → v[1]=8
Afișare inversă: i=0 → v[0]=7
REZULTAT: 9 8 7 ✓
De ce i >= 0 și nu i > 0?

Pentru că vrem să afișăm și primul element (v[0]). Dacă am folosi i > 0, bucla s-ar opri la i=1 și nu am afișa v[0].

Formula cheie pentru parcurgere inversă: for (int i = n-1; i >= 0; i--)

Scrie soluția în C++:
Soluție corectă:
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    const int MAX = 1000;
    int v[MAX];
    
    // Citire elemente
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    
    // Afișare inversă
    for (int i = n - 1; i >= 0; i--) {
        cout << v[i] << " ";
    }
    
    return 0;
}
Varianta cu verificare dimensiune:
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    // Verificăm ca n să fie pozitiv și mai mic decât dimensiunea maximă
    if (n <= 0) {
        cout << "n trebuie sa fie pozitiv!";
        return 0;
    }
    
    const int MAX = 1000;
    if (n > MAX) {
        cout << "n este prea mare!";
        return 0;
    }
    
    int v[MAX];
    
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    
    for (int i = n - 1; i >= 0; i--) {
        cout << v[i] << " ";
    }
    
    return 0;
}

Ce învățăm din această problemă:

  • Parcurgere inversă: de la n-1 la 0 cu decrementare (i--)
  • Condiția corectă: i >= 0 pentru a include primul element
  • Primul și ultimul element:
  • Primul: v[0] (index minim)
  • Ultimul: v[n-1] (index maxim)
  • Verificare date de intrare: bună practică pentru programe robuste
  • Parcurgeri diferite: crescătoare vs descrescătoare
EXERCIȚII PRACTICE - 10 minute

Exercițiul Practic: Primii pași cu vectori

Sarcini de lucru

Completează următoarele sarcini pentru a-ți consolida cunoștințele despre vectori

Sarcina 1: Analiză și corectare cod

Analizează următorul cod și găsește greșelile:

#include <iostream>
using namespace std;

int main() {
    int n = 5;
    int vector[5];
    
    // Citire
    for (int i = 1; i <= n; i++) {
        cin >> vector[i];
    }
    
    // Afișare
    for (int i = 0; i <= n; i++) {
        cout << vector[i];
    }
    
    return 0;
}
Soluție pentru Sarcina 1:

Greșeli identificate și corecții:

  • 1. Indexare greșită la citire: for (int i = 1; i <= n; i++) este greșit.
    Corect: for (int i = 0; i < n; i++)
  • 2. Accesare element inexistent la citire: Când i = 5, se încearcă accesarea vector[5], dar vectorul are doar elementele 0-4.
  • 3. Indexare greșită la afișare: for (int i = 0; i <= n; i++) este greșit (merge până la 5).
    Corect: for (int i = 0; i < n; i++)
  • 4. Lipsă spații la afișare: cout << vector[i]; va afișa numerele lipite.
    Corect: cout << vector[i] << " ";

Cod corectat:

#include <iostream>
using namespace std;

int main() {
    int n = 5;
    int vector[5];
    
    // Citire CORECTĂ
    for (int i = 0; i < n; i++) {
        cin >> vector[i];
    }
    
    // Afișare CORECTĂ
    for (int i = 0; i < n; i++) {
        cout << vector[i] << " ";
    }
    
    return 0;
}
Sarcina 2: Implementare completă

Cerință: Scrie un program care citește n, apoi n numere. Programul afișează: 1. Elementele în ordinea citirii 2. Elementele în ordine inversă 3. Doar elementele de pe poziții pare (0, 2, 4...)

Soluție pentru Sarcina 2:
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    const int MAX = 1000;
    int v[MAX];
    
    // 1. Citire elemente
    for (int i = 0; i < n; i++) {
        cin >> v[i];
    }
    
    cout << "Elementele in ordinea citirii: ";
    // 2. Afișare ordine citire
    for (int i = 0; i < n; i++) {
        cout << v[i] << " ";
    }
    cout << endl;
    
    cout << "Elementele in ordine inversa: ";
    // 3. Afișare ordine inversă
    for (int i = n - 1; i >= 0; i--) {
        cout << v[i] << " ";
    }
    cout << endl;
    
    cout << "Elementele de pe pozitii pare (0, 2, 4...): ";
    // 4. Afișare poziții pare
    for (int i = 0; i < n; i++) {
        if (i % 2 == 0) {  // i este par
            cout << v[i] << " ";
        }
    }
    cout << endl;
    
    return 0;
}

Explicații importante:

  • Poziții pare: Indicele 0 este considerat par, 1 impar, 2 par, etc.
  • Condiția pentru par: i % 2 == 0
  • Afisare clară: Adăugăm mesaje explicative înainte de fiecare afișare
  • Endl după fiecare secvență: Pentru o afișare mai ordonată
  • Teste recomandate:
  • n=5, valori: 1 2 3 4 5
  • n=3, valori: 10 20 30
  • n=1, valori: 100

Descarcă toate exercițiile și soluțiile