Sunteți pe pagina 1din 2

Vectori de frecvență

Când sunt utili ? Atunci când am foarte multe numere, dar aceste numere au valori mici.

Exemplu
Am un fișier cu maxim 1 milion de cifre. Să se afișeze cifrele care nu apar în fișier.

Var. 1
Folosesc 10 contori pentru fiecare cifră (c0,c1,c2,...,c9) și , pe măsură ce citesc fiecare cifră, cresc contorul cifrei
respective; contorul care a ramas 0 , corespunde cifrei care nu există în fișier.
Obs : cum rezolvam problema dacă aveam numere și de o cifră și de 2 cifre? Foloseam 100 de contori, pentru
fiecare număr de la 0 la 99 ?

Var.2
Pozițiile într-un vector încep de la 0
Dacă declar int v[20]; înseamnă că elementele vectorului sunt v[0], v[1], v[2],..., v[19].

Asociez aceste poziții cifrelor  e nevoie de un vector cu 10 poziții ,deoarece:


 pentru cifra 0 , mă folosesc de v[0]
 pentru cifra 1 , mă folosesc de v[1]
 pentru cifra 2 , mă folosesc de v[2]
...
 pentru cifra 9 , mă folosesc de v[9]

date.in
5 3 2 3 3 5 9 7 7 7 7 2 2 2 2 3 5 3 5 3 5 3 9 2 2 2 3 3 3 9 9 9 0 534 cifre

Poziție=cifră=i 0 1 2 3 4 5 6 7 8 9
Element V[0] V[1] V[2] V[3] V[4] V[5] V[6] V[7] V[8] V[9]
Nr.apariții/frecvență 1 0 8 10 0 6 0 4 0 5

Dacă adunăm frecvențele, ar trebui să obținem numărul total de cifre din fișier! 1+8+10+6+4+5=34
am simulat 10 contori cu ajutorul pozițiilor din vector, adică poziția 0 ar fi contorul cifrei 0, poziția 7 ar fi
contorul cifrei 7
*avantaj - nu e nevoie de 10 contori, pentru că îi simulez cu ajutorul pozițiilor din vector
V[3]=10  cifra 3 apare de 10 ori !

Obs : acest vector trebuie să aibă inițial valoarea 0 (contorii să fie resetați pentru fiecare pozițiecifră)
int v[10], cifra,i; cifra=5 v[5]=1
int main() cifra=3 v[3]=1
{ cifra=2 v[2]=1
while (fin>>cifra) cifra=3 v[3]=2
v[cifra]++; cifra=3 v[3]=3
fout<<”cifrele care nu apar sunt \n”; cifra=5 v[5]=2
for (cifra=0; cifra<=9; cifra++) cifra=9 v[9]=1
if (v[cifra]==0) . . .
fout<<cifra<<” ”; } cifra=5 v[5]=6
OBS- dacă numerele la care ne referim sunt de 2 cifre, vectorul va fi declarat int fr[100] , pentru ca numerele sunt
0,1,2…99 corespunzătoare pozițiilor din vectorul respectiv
- analog dacă numerele sunt de 3 cifre int fr[1000]
- sunt probleme în care se cere afișarea numerelor care nu apar
 nu are importanță de câte ori apare un număr, ci dacă apare sau nu
 valorile din vector vor fi 0- pentru numerele care nu apar și 1- pentru cele care apar
 vector caracteristic

Ex: n=20
1 2 2 4 8 1 1 8 8 8 4 4 4 2 2 2 2 2 2 2
i 0 1 2 3 4 5 6 7 8 9
fr[i] 0 1 1 0 1 0 0 0 1 0

Cifrele care apar sunt : 1,2,4 si 8


Cifrele care nu apar sunt : 0,3,5,6,7,9

CIURUL / SITA LUI ERATOSTENE


- se folosește un vector caracteristic până la poziția 10.000 ( dacă vrem să generăm numerele prime până la 10.000)
- inițial, toate valorile din vector sunt 0 ( adică toate pozițiile din vector le considerăm numere prime)
- se pornește de la poziția 2
- dacă pe poziția lui 2 am valoarea 0 ( adică 2 este număr prim)  toți multiplii lui 2 trebuie să fie trecuți pe 1
( în acest moment, jumătate din numere vor fi setate pe 1, deoarece jumătatate dintre ele sunt pare)
- continuăm cu următoarea poziție din vector care are setată valoarea 0 ( adică următorul număr prim)
- dacă pe poziția 3 am valoarea 0 ( adică 3 este număr prim)  toți multiplii lui 3 trebuie să fie trecuți pe 1
- și așa mai departe până când se ajunge la final
- pozițiile care au rămas cu valoarea 0 reprezintă numerele prime

Poz- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ... 10.000


i
Fr[i] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2-este primtoti multiplii lui trec pe 1
0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
3-este prim toti multiplii lui trec pe 1
1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1
5-este prim toti multiplii lui trec pe 1.....
0 0 0 0 1 0 1 0 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 ... 1

int ciur[10000] ,i,j;


int main()
{
for (int i = 2; i <= 10000; i++) // Parcurgem vectorul.
if ciur[i]==0) // Dacă numărul curent este prim,
for (int j = 2 * i; j <= 10000; j =j + i) // parcurgem multiplii săi
ciur[j] = 1; // și îi marcăm cu 1, adica neprime

cout<< “numerele prime sunt \n”;


for (int i = 2; i <= 10000; i++)
if ciur[i]==0)
cout<< i <<” “;
(variantă optimizată la https://www.geeksforgeeks.org/sieve-of-eratosthenes/)
Rezolvați : #0303 - Eratostene #1145 - Extraprime, #1005,#187,#244, #264.

S-ar putea să vă placă și