Prelucrarea unui șir de numere (fără vectori)
Până acum, am lucrat de obicei cu unul sau două numere: am citit un număr, l-am descompus în cifre, i-am calculat divizorii etc.
Dar în multe probleme, primim mai multe numere și trebuie să le prelucrăm:
- să aflăm cel mai mare sau cel mai mic;
- să calculăm suma sau media lor;
- să numărăm câte au o anumită proprietate;
- să aflăm câte sunt pare, câte sunt prime etc.
Cum citim mai multe numere?
De obicei, pe prima linie primim un număr n care
ne spune câte valori urmează.
Apoi, pe a doua linie, primim cele n numere.
Exemplu:
Input:
5
3 7 2 9 4Aici avem n = 5 și numerele sunt:
3, 7, 2, 9, 4.
Ideea de bază
Citim numerele unul câte unul într-o buclă
forși le prelucrăm imediat, fără a le stoca pe toate.
Nu avem nevoie de vectori. Folosim o singură variabilă
x pe care o citim de n ori:
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
// prelucrăm x aici
}La fiecare pas, x primește o nouă valoare și o
putem folosi cum dorim.
Suma a n numere
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int suma = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
suma = suma + x;
}
cout << suma;
return 0;
}Input:
4
10 20 30 40Output:
100Ce face programul?
| Pas | x citit | suma |
|---|---|---|
| start | - | 0 |
| 1 | 10 | 0 + 10 = 10 |
| 2 | 20 | 10 + 20 = 30 |
| 3 | 30 | 30 + 30 = 60 |
| 4 | 40 | 60 + 40 = 100 |
Media aritmetică
Media aritmetică = suma tuturor numerelor împărțită la câte numere sunt.
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int suma = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
suma = suma + x;
}
cout << suma / n;
return 0;
}Input:
4
10 20 30 40Output:
25Atenție: dacă vrem media cu zecimale,
trebuie să folosim double:
cout << (double)suma / n;
Maximul unui șir de numere
Vrem să aflăm cea mai mare valoare din cele n
numere.
Ideea
- citim primul număr și presupunem că el este maximul;
- pentru fiecare număr următor, verificăm dacă este mai mare decât maximul curent;
- dacă da, actualizăm maximul.
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int x;
cin >> x;
int maxim = x;
for (int i = 2; i <= n; i++) {
cin >> x;
if (x > maxim) {
maxim = x;
}
}
cout << maxim;
return 0;
}Input:
5
3 7 2 9 4Output:
9Pas cu pas
| Pas | x citit | maxim |
|---|---|---|
| 1 | 3 | 3 |
| 2 | 7 | 7 (7 > 3) |
| 3 | 2 | 7 (2 < 7) |
| 4 | 9 | 9 (9 > 7) |
| 5 | 4 | 9 (4 < 9) |
Minimul unui șir de numere
La fel ca maximul, dar folosim < în loc de
>:
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int x;
cin >> x;
int minim = x;
for (int i = 2; i <= n; i++) {
cin >> x;
if (x < minim) {
minim = x;
}
}
cout << minim;
return 0;
}Input:
5
3 7 2 9 4Output:
2Numărarea valorilor cu o proprietate
Câte numere pare sunt?
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int cnt = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (x % 2 == 0) {
cnt++;
}
}
cout << cnt;
return 0;
}Input:
6
3 8 2 7 4 1Output:
3Cele pare sunt: 8, 2,
4 → trei numere.
Câte numere sunt mai mari decât o valoare dată?
#include <iostream>
using namespace std;
int main()
{
int n, prag;
cin >> n >> prag;
int cnt = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (x > prag) {
cnt++;
}
}
cout << cnt;
return 0;
}Input:
5 5
3 7 2 9 4Output:
2Numerele mai mari decât 5 sunt: 7
și 9.
Maximul și poziția lui
Uneori vrem să știm nu doar care este maximul, ci și al câtelea număr este.
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int x;
cin >> x;
int maxim = x;
int pozitie = 1;
for (int i = 2; i <= n; i++) {
cin >> x;
if (x > maxim) {
maxim = x;
pozitie = i;
}
}
cout << "Maximul este " << maxim << endl;
cout << "Se afla pe pozitia " << pozitie;
return 0;
}Input:
5
3 7 2 9 4Output:
Maximul este 9
Se afla pe pozitia 4Combinarea mai multor prelucrări
Putem calcula mai multe lucruri în aceeași buclă:
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int x;
cin >> x;
int suma = x;
int maxim = x;
int minim = x;
int cnt_pare = 0;
if (x % 2 == 0) cnt_pare++;
for (int i = 2; i <= n; i++) {
cin >> x;
suma = suma + x;
if (x > maxim) maxim = x;
if (x < minim) minim = x;
if (x % 2 == 0) cnt_pare++;
}
cout << "Suma: " << suma << endl;
cout << "Maxim: " << maxim << endl;
cout << "Minim: " << minim << endl;
cout << "Numere pare: " << cnt_pare << endl;
return 0;
}Input:
5
3 7 2 9 4Output:
Suma: 25
Maxim: 9
Minim: 2
Numere pare: 2De reținut: nu avem nevoie de o buclă separată pentru fiecare calcul. Totul se poate face într-o singură parcurgere!
Citirea până
la o valoare specială (fără n)
Uneori nu știm dinainte câte numere urmează. Primim numere
până când apare o valoare specială (de exemplu
0):
#include <iostream>
using namespace std;
int main()
{
int x;
int suma = 0;
int cnt = 0;
cin >> x;
while (x != 0) {
suma = suma + x;
cnt++;
cin >> x;
}
cout << "Am citit " << cnt << " numere" << endl;
cout << "Suma lor este " << suma;
return 0;
}Input:
3 7 2 9 0Output:
Am citit 4 numere
Suma lor este 21Cum funcționează?
- citim un număr;
- dacă nu este
0, îl prelucrăm și citim altul; - când întâlnim
0, ne oprim.
De ce citim x de două ori?
Prima citire (cin >> x de dinaintea
buclei) este necesară pentru a avea o valoare pe care să o
verificăm înainte de a intra în buclă.
Dacă primul număr este chiar 0, bucla nu se
execută deloc - ceea ce este corect.
Citirea din interiorul buclei pregătește următoarea valoare
pentru a fi verificată la condiția while.
Greșeli frecvente
1. Inițializarea greșită a maximului
int maxim = 0; // GREȘIT dacă numerele pot fi negativeDacă toate numerele sunt negative, maximul ar rămâne
0, ceea ce e incorect.
Soluția corectă: inițializăm maximul cu primul număr citit.
2.
Bucla pornește de la 1 în loc de 2 la
maxim/minim
Dacă am citit deja primul număr înaintea buclei, bucla
trebuie să pornească de la i = 2:
cin >> x; // citim primul
int maxim = x;
for (int i = 2; i <= n; i++) { // de la al doilea
cin >> x;
...
}Dacă pornim de la 1, vom citi n + 1
numere în total.
3. Uitarea contorului la numărare
if (x % 2 == 0) {
// lipsește cnt++;
}Dacă verificăm o condiție dar nu incrementăm contorul,
rezultatul va fi mereu 0.
4. Împărțire la zero la media aritmetică
Dacă n = 0, operația suma / n va da
eroare. Trebuie verificat:
if (n > 0) {
cout << suma / n;
}Ce să reții
- Putem prelucra un șir de numere fără vectori, citind fiecare valoare pe rând.
- Folosim o variabilă
xpe care o recitim la fiecare pas. - Suma, maximul, minimul, numărarea - toate se pot face într-o singură parcurgere.
- Maximul și minimul se inițializează cu primul
element, nu cu
0. - Bucla pornește de la
2dacă am citit deja primul element separat. - Totul se bazează pe cunoștințele anterioare:
for,while,if,cin.