TOT CE AI NEVOIE pentru SUBIECTUL III, EXERCITIUL III

Cum citești dintr-un fișier

fstream, citire în buclă, procesare pe loc fără să stochezi tot șirul în memorie.

Deschiderea și citirea fișierelor cu ifstream

La Subiectul III, Exercițiul 3, datele de intrare vin dintr-un fișier text, nu de la tastatură. Trebuie să știi să deschizi fișierul, să citești valorile și, cel mai important, să faci asta fără să încarci tot fișierul într-un vector dacă problema cere memorie eficientă.

Deschiderea fișierului

#include <fstream>
using namespace std;

ifstream fin("date.in");

Dacă fișierul nu există sau nu poate fi deschis, fin intră în stare de eroare. Poți verifica asta cu fin.is_open() sau, mai simplu la BAC, presupui că fișierul există (așa cum e mereu specificat în cerință).

Citirea valorilor fără să știi câte sunt

Multe probleme de Subiectul III nu îți spun direct câte numere sunt în fișier. În acest caz, citești în buclă până la finalul fișierului:

int x;
while (fin >> x) {
    // prelucrezi x aici, fără să îl stochezi într-un vector
}

Operatorul >> întoarce fluxul fin, care este evaluat ca false când citirea eșuează (adică atunci când fișierul s-a terminat). Acesta este tiparul standard pentru citirea eficientă ca memorie: procesezi fiecare număr imediat ce îl citești, apoi îl uiți.

Închiderea fișierului

fin.close();

Nu este obligatoriu la BAC (fișierul se închide automat când fin iese din scop), dar e o bună practică să îl incluzi.

Notă: La BAC: dacă cerința zice explicit "algoritm eficient din punct de vedere al memoriei utilizate", ăsta e semnalul că NU ai voie să încarci toate valorile într-un vector. Trebuie să le prelucrezi pe măsură ce le citești, folosind doar câteva variabile auxiliare.

Exemplu rezolvat: citire simplă din fișier

Cerința

Fișierul date.in conține pe o singură linie un număr necunoscut de numere naturale, separate prin spațiu, cel mult 999999999 fiecare. Să se afișeze suma și numărul de valori pare din fișier, folosind un algoritm eficient din punct de vedere al memoriei utilizate.

Rezolvare

#include <fstream>
#include <iostream>
using namespace std;

int main() {
    ifstream fin("date.in");
    long long suma = 0;
    int nrPare = 0;
    int x;

    while (fin >> x) {
        suma += x;
        if (x % 2 == 0) nrPare++;
    }

    fin.close();
    cout << suma << " " << nrPare;
    return 0;
}

De ce este eficient

Folosim doar trei variabile (suma, nrPare, x), indiferent dacă fișierul are 10 sau 10 milioane de numere. Memoria folosită este constantă, O(1), nu depinde de câte valori sunt în fișier. Asta e diferența față de a citi totul într-un vector, unde memoria ar crește odată cu numărul de valori, O(n).

Atenție la tipul de date

Suma poate depăși limita lui int (aproximativ 2.1 miliarde). Dacă ai multe numere mari, folosește long long pentru sumă, ca în exemplul de mai sus.