Sunteți pe pagina 1din 5

Vectorul de frecvene i aplicaii

Vectorul de frecvene reine numrul de apariii al fiecrei valori citite ntr-un vector. Folosirea
vectorului de frecvene permite scrierea unor algoritmi eficieni n cazul n care datele de intrare au valori
dintr-un domeniu cunoscut care poate fi prelucrat rapid. Folosirea unui vector de frecven sau
marcare este eficient numai n cazul n care valorile care intereseaz sunt ntregi i numrul
valorilor distincte posibile este cel mult 1.000.000 pentru un timp maxim de 1 sec/test.
De exemplu acest vector poate fi folosit pentru sortarea rapid a datelor, n timp liniar.
Tot cu ajutorul acestui vector pot fi implementate operaiile de baz cu mulimi:
- Cutarea unui element
- Intersecia a dou (sau mai multe) mulimi
- Reuniunea a dou (sau mai multe) mulimi
n orice mulime elementele sunt unice, iar vectorul frecvenelor are doar valori 0 sau 1. Acest vector
este numit vectorul caracteristic al unei mulimi. Vectorul de frecvene poate fi folosit pentru a obine
rapid mulimea asociat ca un vector caracteristic astfel:
- 0 nseamn c elementul nu aparine mulimii
- o valoare diferit de 0 nseamn c elementul aparine mulimii
APLICAII ale vectorului de frecvene sau vectorului caracteristic al unei mulimi:
1. Prelucrarea cifrelor
2. Sortare n timp liniar
3. Operaii cu mulimi

1. Prelucrarea cifrelor unui numr
Aplicaie rezolvat Cifre distincte:
Fiind dat un numr natural n ntre 1 i dou miliarde s se afieze cifrele i numrul de
elemente al mulimii cifrelor sale.
Date de intrare
Fiierul de intrare cfdist.in conine numrul n.
Date de ieire
Fiierul de ieire cfdist.out va conine un singur numr, numrul de cifre distincte ale lui n.
Restricii
1 n 2.000.000.000
Exemplu
cfdist.in cfdist.out
234234234 3
Explicaie
Numrul 234234234 conine 3 cifre distincte, 2, 3 i 4.
Vectorul de frecven pentru cifrele unui numr se declar sub forma unui vector cu 10 componente, de la
a[0],,a[9]. Acestea vor fi iniializate cu 0, iar dup citirea numrului n se va incrementa cu 1 numrul
apariiilor pentru fiecare cifr a lui n.
Atenie! Vectorul de frecvene nu permite refacerea numrului citit iniial, dac este necesar valoarea
acestuia trebuie memorat separat.
Soluie: Codul C++ este dat n continuare:
1. #include<iostream>
2. using namespace std;
3. int a[10],n;
4.
5. int main()
6. {
7. int i,nn,nc=0;
8. cout<<"n=";
9. cin>>n;
10. nn=n;//clonam valoarea n in variabila nn
11. while(nn>0) //construim vectorul frecventelor
12. { a[nn%10]++;
13. nn=nn/10;}
14. //afisam cifrele distincte
15. for(i=0;i<10;i++)
16. if (a[i]>0) {cout<<i;nc++;}
17. cout<<'\n'<<nc<<" cifre distincte";
18. return 0;
19. }
1. Cifre comune: Se citesc dou numere naturale n i m. S se afieze numrul de cifre
distincte comune ambelor numere.
Indicaie de rezolvare: Construim vectorii de frecven pentru fiecare numr i apoi aflm
cifrele comune. Dac notm cu a vectorul de frecvene al lui n i cu b vectorul de frecvene
al lui b condiia ca cifra c s fie comun este a[c]>0 && b[c]>0.
2. Maxnr: Dat un numr natural n ntre 1 i dou miliarde s se afieze cel mai mare
numr care se poate forma cu cifrele sale.
Indicaie de rezolvare: Construim vectorul de frecvene asociat numrului n, notat cu a.
Numrul maxim care poate fi format cu cifrele sale se obine prin parcurgerea n ordine
descresctoare, de la 9 la 0, a vectorului de frecvene i scriind fiecare cifr c de a[c] ori.
3. Minnr: Dat un numr natural n ntre 1 i dou miliarde s se afieze cel mai mic numr
care se poate forma cu cifrele sale.
Indicaie de rezolvare: Construim vectorul de frecvene asociat numrului n, notat cu a.
Avem dou situaii posibile: a) numrul n nu are cifra 0 sau b) numrul n conine i cifra 0.
a) Numrul minim se obine prin parcurgerea n ordine cresctoare, de la 1 la 9, a
vectorului frecvenelor i afiarea fiecrei cifre c de a[c] ori.
b) Se determin prima cifr nenul a lui n i se afieaz ca prima cifr a rezultatului. Dup
prima cifr se afieaz toate zerourile care apar n n, iar apoi se aplic acelai algoritm
ca n cazul a.

4. Minnrk: Se citesc dou numere, n i k. S se afieze cel mai mic numr de k cifre care
se poate forma cu cifrele lui n.
Indicaie de rezolvare: Construim vectorul de frecvene asociat numrului n, notat cu a.
Avem dou situaii posibile: a) numrul n nu are cifra 0 sau b) numrul n conine i cifra 0.
Aplicm acelai algoritm de la problema Minnr, dar afim doar primele k cifre din numrul
rezultat.

5. Cifre1: Se dau dou numere naturale a i b cu maxim 9 cifre.
a) S se determine cifrele distincte, comune numerelor a i b.
b) S se afieze numrul cel mai mare format din toate cifrele lui a i b.

2. Sortare n timp liniar
Culori (clasa a 5-a)
Se d o secven de n culori codificate cu numere ntre 1 i 99. S se afieze culorile n ordinea
lor cresctoare. Acesta este un exerciiu introductiv n folosirea vectorilor de frecven.
Date de intrare
Fiierul de intrare culori.in va conine pe prima linie numrul n. Pe a doua linie va conine n
numere desprite prin spaiu.
Date de ieire
n fiierul de ieire culori.out vei scrie o singur linie coninnd cele n culori n ordine
cresctoare.
Restricii
1 n 1.000.000
1 culoare 99
Exemplu
culori.in culori.out
10
4 7 3 0 3 7 4 0 2 2
0 0 2 2 3 3 4 4 7 7
Explicaie
Cele zece culori de la intrare au fost afiate n ordine cresctoare.
Soluie
Construim vectorul de frecven a cifrelor a[0], , a[9] i afim cifrele n ordine cresctoare
de la 0 la 9, iar fiecare cifr c va fi scris de a[c] ori.


3. Operaii cu mulimi

A. ntr-o mulime n sens matematic - set, elementele au valori distincte iar vectorul de
frecvene se numete vector caracteristic. Dac mulimea A are valorile din mulimea
{0,1,2,,n} vectorul caracteristic al mulimii A este definit prin:
[] {




1. Iniializarea vectorului caracteristic:
1. void citire(int &n, int a[])
2. {
3. int i,x;
4. for(i=1;i<=n;i++)
5. {cin>>x;
6. a[x]++;}
7. }
2. Testarea apartenenei unui element x la mulimea A:
1. int apartine(int x,int a[])
2. {
3. if(a[x]>0) return 1;
4. else return 0;
5. }
3. Intersecia a dou mulimi A i B de numere naturale din intervalul nchis [0,n].

1. void intersectie(int n,int a[],int b[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]*b[i]>0) cout<<i;
5. }
4. Reuniunea a dou mulimi A i B de numere naturale din intervalul nchis [0,n].

1. void reuniune(int n,int a[],int b[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]+b[i]>0) cout<<i;
5. }
5. Diferena a dou mulimi A i B de numere naturale din intervalul nchis [0,n].

1. void diferenta(int n,int a[],int b[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]>0 && b[i]==0) cout<<i;
5. }



B. O mulime generalizat sau multiset este o colecie de elemente n care este permis ca o
valoare s se repete. Valorile care se repet pot fi considerate identice sau echivalente. De
exemplu, ntr-o list de persoane pot s existe mai multe persoane care au aceeai nlime
sau cu acelai prenume.
Vectorul de frecven reine numrul de apariii al unei valori din multiset:
[]
Citirea i testul de apartenen sunt identice cu cele de la mulimi.

1. Intersecia a dou mulimi generalizate A i B de numere naturale din intervalul nchis [0,n].
1. void intersectie(int n,int a[],int b[],int c[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]<=b[i]) c[i]=a[i];
5. else c[i]=a[i];
6. }
2. Reuniunea a dou mulimi generalizate A i B de numere naturale din intervalul nchis [0,n].
1. void reuniune(int n,int a[],int b[],int c[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]<=b[i]) c[i]=b[i];
5. else c[i]=a[i];
6. }
3. Diferena a dou mulimi generalizate A i B de numere naturale din intervalul nchis [0,n].
1. void diferenta(int n,int a[],int b[],int c[])
2. { int i;
3. for(i=0;i<=n;i++)
4. if(a[i]>b[i]) c[i]=a[i]-b[i];
5. else c[i]=0;
6. }
4. Sortarea cresctoare elementelor unei mulimi generalizate se face printr-o simpl parcurgere a
intervalului [0,n] .
1. void tipar(int n,int a[])
2. { int i,j;
3. for(i=0;i<=n;i++)
4. for(j=0;j<=a[i];j++)
5. cout<<i<<' ';
6. }

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