|
mii de inregistrari.In toate situatiile in care se doreste accesul aleator
|
səhifə | 6/18 | tarix | 12.09.2018 | ölçüsü | 1,36 Mb. | | #81721 |
| mii de inregistrari.In toate situatiile in care se doreste accesul aleator
la un membru al conteinerului se va prefera tipul vector.Tipul stiva se
va utiliza preferential atunci cand nu se executa decat operatii care
intereseaza intreaga serie de obiecte din container (stiva ocupa mai putin
spatiu de memorie si nu se preteaza la erori de adresare).
-33-
Cel mai simplu container contine doar valori de tip numeric:
EXEMPLU: (vezi si cplus24.cpp )
#include
#include
#include
using namespace std;
vector v;
int main()
{
randomize();
cout << "Elementele vectorului sunt: ";
for (int i=0;i<10;i++)
{ int num=(int) rand() %100;
cout << num << " ";
v.push_back(num);
};
cout <<"\n Vectorul contine: " << v.size() << " elemente";
cout <<"\n Primul element este: " << *v.begin();
cout <<"\n Localizat la adresa: " << v.begin();
cout <<"\n Al saptelea element este: " << v.at(6);
cout <<"\n Ultimul element este: " << *v.end();
cout <<"\n Localizat la adresa: " << v.end();
getch();
}
Primul element din container este arhivat la adresa zero.Astfel,atunci
cand se apeleaza un element oarecare prin metoda at() se va specifica
valoarea (n-1) pentru numarul de ordine al elementului.Observati ca datele
de tip INT sunt arhivate in format de 16 de biti (2 bytes). Diferenta
dintre adresa ultimului element si cea a primului element va fi de 20 de
bytes.
Pentru operatiile asupra mebrilor se utilizeaza iteratorii (pointeri).
Pe langa metodele proprii ale fiecarui tip de container,se pot efectua
operatii asupra datelor din container si cu ajutorul unor algoritmi pre-
definiti in biblioteca STL,intr-o fila denumita .Fiecare
fila care defineste containerul incarca automat in memorie si fila
,astfel incat toti acesti algoritmi sunt accesibili in orice
moment.Ca rezultat,un container este incomparabil mai versatil decat un
obiect similar de tip struct sau class,in care fiecare algoritm trebuie
redefinit pentru a putea opera asupra membrilor.
In exemplul precedent am utilizat o functie repetitiva simpla,pentru
a genera zece valori numerice aleatoare,pe care le-am introdus in con-
tainer cu ajutorul metodei push_back().
In continuare,putem efectua diverse operatii automate de cautare si/sau
sortare a elementelor.De exemplu,putem cauta primul element care respecta
o anumita conditie,sau ultimul element care respecta o anumita conditie.
Deasemenea,putem sa excludem selectiv o parte dintre membri si putem sa
formam un nou container,care va contine doar elemenetele selectate.
De exemplu,pentru a cauta primul element par din seria de numere,va
trebui scris un algoritm care parcurge containerul incepand cu primul ele-
ment si imparte la 2 fiecare element.Daca rezultatul este tot un numar de
tip INT,numarul este par (numerele impare returneaza zero ).
-34-
EXEMPLU: (vezi si cplus25.cpp )
#include
#include
#include
using namespace std;
vector v;
int main()
{
randomize();
cout << "Elementele vectorului sunt: ";
for (int i=0;i<10;i++)
{ int num = random(100);
cout << num << " ";
v.push_back(num); };
vector::iterator iter1 = v.begin();
while(iter1 != v.end() && *iter1 %2 !=0){iter1++};
cout << "\n Primul numar par este: " << *iter1;
vector::iterator iter2 = v.end();
do {iter2--}
while(iter2 != v.begin() && *iter2 % 2 != 0 );
cout << Ultimul numar par este: " << *iter2;
cout << "\n vectorul nou este: \n";
if ( iter1 != v.end() && iter2 != v.begin() }
{ vector v2(iter1,iter2);
for(int i=0;i
}
Observati ca am declarat doi iteratori,cu care declarat doi algoritmi de
cautare a primului si a ultimului numar par.Pentru a sorta datele din
container se poate utiliza algoritmul de sortare sort()(din )
EXEMPLU: (vezi si cplus26.cpp )
#include
#include
#include
using namespace std;
vector v;
int main()
{
randomize();
cout << "Elementele vectorului sunt: ";
for (int i=0;i<10;i++)
{ int num=(int) rand() %100;
cout << num << " ";
v.push_back(num); };
sort(v.begin(),v.end() );
cout << "\n Dupa sortare,elementele sunt: \n";
for (int i=0;i<10;i++) cout << v.at(i) << " ";
getch();
}
Sortarea s-a facut prin apelul unei singure proceduri simple.
-35-
Pentru a utiliza structuri de date mai complexe,se declara tipul de
data,apoi un vector din tipul respectiv:
EXEMPLU: (vezi si cplus27.cpp )
#include
#include
#include
using namespace std;
struct date { int varsta;
char *nume; };
date d1,d2,d3,d4;
vector v;
int main()
{
d1.varsta=65;d1.nume="Ion";
d2.varsta=73;d2.nume="Vasile";
d3.varsta=44;d3.nume="Marin";
d4.varsta=22;d4.nume="Mihai";
v.push_back(d1);v.push_back(d2);
v.push_back(d3);v.push_back(d4);
cout << "datele arhivate sunt: \n\n";
for(int i=0;i<4;i++)
{ cout << v.at(i).nume<<" "<
getch();
}
Tipul de conteiner: list
METODE (allocator_type,assign,back,begin,clear,const_iterator,const_refe-
rence,const_reverse_iterator,difference type,empty,end,erase,
front,get_allocator,insert,iterator,list,max_size,merge,pop_back,
pop_front,push_back,push_front,rbegin,reference,remove,remove_if,
rend,resize,reverse,reverse_iterator,size,size_type,sort,splice,
swap,unique,value_type )
EXEMPLU: (vezi si cplus28.cpp )
#include
#include
#include
using namespace std;
typedef list v;
int main()
{ v lista; v::iterator numar; randomize();
for (int i=0;i<10;i++) { lista.push_front(random(100)) ; };
cout << " datele arhivate sunt: \n\n";
for (numar=lista.begin();numar != lista.end();numar++)
cout << *numar << " ";
cout << " \n datele sortate sunt: \n\n";
lista.sort();
for (numar=lista.begin();numar != lista.end();numar++)
cout << *numar << " ";
getch()
}
-36-
Tipul list arhiveaza datele sub forma de lista.Se pot utiliza la fel
ca si vectorii.Prin comparare cu tipul vector,tipul list are timpii de
insertie si excludere a datelor mai scurti,dar are timpul de acces la
fiecare membru mai lung.Pentru aplicatiile in care arhiva se schimba
foarte frecvent prin introducerea si stergerea datelor,se va prefera tipul
list,iar pentru cele in care datele vor fi doar consultate frecvent,se va
prefera tipul vector.Tipul list nu are functia at().Ca rezultat apelarea
datelor se va face obligatoriu cu ajutorul unui iterator (sau pointer).
Elementele incluse pot avea dimensiuni variabile iar deplasarea se poate
face bidirectional.
Tipul map
METODE ( allocator_type,begin,clear,const_iterator,const_reference,count,
const_reverse_iterator,difference_type,empty,end,equal_range,
erase,find,get_allocator,insert,iterator,key_comp,key_compare,
key_type,lower_bownd,map,max_size,operator[],rbegin,reference,
referent_type,rend,reverse_iterator,size,size_type,swap,
upper_bound,value_comp,value_compare,value_type )
EXEMPLU: (vezi si cplus29.cpp )
#include
#include
#include
using namespace std;
typedef map > m1;
int main()
{
m1 zi;
m1::iterator it1;
zi[1]=35;
zi[2]=2;
zi[3]=44;
zi[4]=17;
zi[5]=55;
zi[6]=23;
zi[7]=15;
cout << "\n Conteinerul poate accepta: " <
cout << "\n Conteinerul contine urmatoarele perechi: \n\n";
for (int i=0;i<8;i++)
{ it1=zi.find(1);
cout << (*it1).first << " " << (*it1).second << "\n";
};
getch();
}
Tipul map opereaza cu colectii de date sortate asociativ sub forma de
perechi de tipul key/value (cod/valoare).Astfel datele de un anumit tip
pot fi sortate in functie de cel de al doilea tip.In versiunile mai noi
de program (care accepta si tipul "string" ) se utilizeaza pentru perechi
de tipul string/int sau string/float etc.Primul element din pereche
trebuie sa fie de tip constant ( type pair ) si va fi uti-
lizat pentru sortarea celui de al doilea element.
-37-
In tipul map se pot introduce sau sterge elemente,la orice pozitie.
Introducerea unui element nou nu invalideaza iteratorii preexistenti,iar
stergerea unui element nu invalideaza decat iteratorul spre elementul
sters (restul raman valabili).Accesul la membri se poate face doar prin
iteratori (pointeri).In tipul map,elementul Key trebuie sa fie unic.In
tipul multimap elementul Key nu este obligatoriu sa fie unic (pot exista
doua sau mai multe perechi in care key este diferit dar contin aceeasi
valoare).In rest,multimap este identic cu map.
Tipul deque (double ended queue)
METODE ( allocator_type,assign,at,back,begin,clear,const_iterator,
const_reference,const_reverse_iterator,deque,difference_type,empty
end,erase,front,get_allocator,insert,iterator,max_size,operator[],
pop_back,pop_front,push_back,push_front,rbegin,reference,rend,
resize,reverse_iterator,size,size_type,swap,value_type )
EXEMPLU: (vezi si cplus30.cpp )
#include
#include
#include
using namespace std;
typedef deque text1;
void scrie(deque n);
void main()
{
text1 a(5,'A');
scrie(a);
a.insert(a.begin(),'X');
scrie(a);
a.insert(a.end(),'Y');
scrie(a);
a.insert(a.begin()+4,3,'M');
cout<< "\n\nDimensiunea stivei este: " <
cout<< "Dimensiunea maxima a stivei este: "<
scrie(a);
getch();
}
void scrie(deque n)
{
text1::iterator it1;
text2::reverse_iterator it2;
cout << "\n Elementele stivei sunt: \n";
for (it1=n.begin();it1 != n.end(); it1++ )
cout << *it1 << " ";
cout << "\n In ordine inversa sunt: \n";
for (it2=n.begin();it2 != n.rend(); it2++)
cout << *it2 << " ";
}
Tipul deque nu trebuie confundat cu tipul queue.Chiar daca este tot
sub forma de stiva,stiva cu doua capete seamana mai mult cu tipul vector.
Accesul este aleator,la orice membru,inclusiv prin functia at() sau prin
-38-
iteratori si pointeri.Insertia este mai rapida la capetele stivei si mai
lenta in mijlocul stivei.Inserarea unui element nou invalideaza itera-
torii existenti.Pentru a afisa datele in mod repetat,am definit o functie
speciala in care am utilizat atat iteratorul incremental cat si pe cel
decremental.Observati ca pentru citirea prin decrementare se utilizeaza
rbegin() si rend(),astfel incat datele sa fie parcurse de la celalalt
capat al stivei.Se poate utiliza in aceleasi situatii ca si tipul vector,
dar cu particularitatile pe care le prezinta tipul stiva.Pentru accesul
rapid la membri se va prefera intotdeauna tipul vector.Acest tip de data
este recomandabil mai ales pentru compatibilitatea cu programele foarte
vechi,in care datele sunt arhivate in stive si pot fi preluate foarte
usor cu ajutorul unei alte stive.
Tipul set
METODE (allocator_type,begin,clear,const_iterator,const_reference,
const_reverse_iterator,count,difference_type,empty,end,equal_range
erase,find,get_allocator,insert,iterator,key_comp,key_compare,
key_type,lower_bound,set,max_size,rbegin,reference,rend,
reverse_iterator,size,size_type,swap,upper_bound,value_comp,
value_compare,value_type )
EXEMPLU: ( vezi si cplus31.cpp )
#include
#include
#include
using namespace std;
typedef set > set1;
int main()
{
set1 s1;
set1::reverse_iterator it1;
set1::iterator it2;
s1.insert(333);
s1.insert(17);
s1.insert(54);
s1.insert(888);
cout << "\n valorile in ordine inversa sunt: \n";
for (it1=s1.rbegin();it1 != s1.rend(); it1++)
cout << *it1 << " ";
cout << "\n valorile in ordinea introducerii: \n";
for (it2=s1.begin();it2 != s1.end(); it2++)
cout << *it2 << " ";
getch();
}
Tipul set este asemantor cu tipul map,dar contine serii de elemente unice
de dimensiune variabila.Elementele ( type const Key ) sunt de tip Key,dar
spre deosebire de tipul map,fiecare element este si key si value.Ca re-
zultat sortarea se va face utilizand valoarea elementului.Se pot introduce
sau sterge elemente la orice pozitie.Timpul per operatie depinde de nu-
marul de elemente din serie (logarthmic time).Insertia de elemente nu
invalideaza iteratorii preexistenti.Stergerea invalideaza doar iteratorul
-39-
elementului eliminat.Pentru tipul set,fiecare element trebuie sa fie unic
(nu pot exista doua elemente cu aceeasi valoare).Tipul multiset permite
mai multe elemente identice,astfel incat pot exista mai multe inregistrari
cu aceeasi valoare.
Restul tipurilor de conteinere au o valoare mai limitata si se utilizeaza
mai ales pentru compatibilitatea cu programele mai vechi,in care datele
au fost arhivate in astfel de structuri.Nu se vor prezenta exemple,deoa-
rece nu se recomanda utilizarea acestor tipuri pentru aplicatiile dez-
voltate in etapa actuala (mecanismul de tip LIFO si FIFO executa un
numar extrem de mare de operatii inutile,care uzeaza procesorul fara nici
o justificare moderna).
Tipul stack
METODE (empty,pop,push,size,top)
Tipul stack(stiva) utilizeza mecanismul LIFO (Last In First Out).Fiecare
element trebuie introdus cu PUSH si poate fi scos cu POP.Nu se poate
ajunge la un element central decat dupa ce au fost scoase toate elemente-
le anterioare (capul stivei).Elementele care urmeaza dupa cel selectat
formeaza coada stivei.Pentru operatii se utilizeaza o stiva auxiliara.
Tipul queue
METODE (back,empty,front,pop,push,size,top)
Tipul queue este asemanator cu stack dar utilizeaza mecanismul FIFO
(First In First Out).Fiecare element trebuie introdus cu PUSH si poate fi
extras cu POP.Primul element introdus este si primul care va fi extras.
Stiva a fost reordonata automat cu ajutorul unei stive auxiliare.
Tipul bitset
METODE (any,count,flip,none,reset,set,size,test,to_string,to_ulong)
Contine secvente de biti.Grupurile de biti se pot manipula cu operatorii
binari AND,OR etc.Grupurile de biti se pot si formata sub forma de siruri
de caractere sau de numere de tip unsigned INT daca se apeleaza cele
doua metode specializate "to_string" si "to_ulong".Acest tip de data
este foarte util pentru programele de analiza ("parsing") si permite o
abordare complexa a fiecarui grup de biti dintr-un program.Poate fi
utilizat cu succes si pentru a scrie programe care formateaza datele sau
convertesc un format in alt format de date.Nu se recomanda incepatorilor.
Orice eroare elementara prin care "se pierde sau se adauga un bit " poate
determina transformari ireversibile.Se poate utiliza si pentru aplicatiile
care opereaza cu imagini digitale,sunete,arii Bitmap etc. dar cu prudenta
necesara pentru operatiile "la nivel inferior".
Toate containerele au acces si la fila care contine un
grup de circa 70 de algoritmi predefiniti (dintre care sort() a fost
utilizat in exemple).Acesti algoritmi acopera majoritatea operatiilor ce
pot fi executate asupra datelor din structuri.Consultati si acesti algo-
ritmi inainte de a va lansa in operatii complicate de definire a unor
algoritmi noi.Este foarte probabil sa gasiti exact ceea ce aveti nevoie
si sa scutiti astfel un efort inutil.Daca realizati algoritmi valorosi,
de interes general,arhivati acesti algoritmi intr-o fila similara.
-40-
La fel ca si containerele,filele sunt structuri ordonate de date,cu un
nume identificator distinct,organizate sub forma de documente si utilizate
pentru a stoca grupuri mari de date.Datele continute intr-o fila pot fi
de acelasi tip (Exemplu : fila tip text),sau pot fi organizate in doua sau
mai multe tipuri de date distincte.Sistemele de operare si programele di-
ferite,vor genera o mare varietate de file cu continut si extensie dife-
rita de la un program la altul.Astfel de file pot fi: file tip text,tabele
si baze de date tip Fox,Oracle sau Excel,file tip hipertext(HTML),file
care contin date binare(binary data),file care contin arii de biti(file
tip BitMap.bmp),diverse tipuri de imagini digitale(.jpg sau .avx),file
care contin inregistrari muzicale sau sunete(.wav,.mp3) etc.Programul C++
poate deschide orice tip de fila,dar prelucrarea si interpretarea datelor
trebuie sa fie facuta cu ajutorul unor obiecte care recunosc formatul in
care au fost editate datele.
Nu exista o solutie unica.Cu ajutorul functiilor si al obiectelor pre-
definite se pot concepe o larga varietate de solutii,in functie de tipul
de data analizat si de necesitatile de moment.In plus,in permanenta apar
noi biblioteci de clase si obiecte,care sunt specializate pentru operatii
cu file de un anumit fel.Turbo C++ nu contine obiecte specializate pentru
filele HTML,.JPG.AVI etc. dar poate deschide si prelua datele din orice
tip de fila.Pentru interpretarea lor trebuie sa definiti obiectele si
procedurile care prelucreaza datele.Visual C++ (prin MFC) contine deja
o serie de obiecte specializate.De exemplu,pentru fielele de tip HTML
exista clasa CHtmlView care este conceputa special pentru a putea edita
file de tip HTML prin care programele scrise in C++ "posteaza" informatii
pe Internet.Exista si o serie intreaga de biblioteci de obiecte create
special pentru operatii cu si asupra filelor specializate.
Programul C++ ofera solutii diferite pentru filele de tip DOS,fata de
cele de tip Windows.Prima solutie posibila este sa utilizati functiile
mostenite din C (stdio.h):
EXEMPLU: (vezi si cplus32.cpp )
#include
Dostları ilə paylaş: |
|
|