Sunteți pe pagina 1din 16

Condiţiile de evaluare la Laboratorul nr.

1 „Metode de căutare în tabele” la SDMP

Nr. de
puncte
Să se creeze un fişier textual care conţine cel puţin 50 de înregistrări, cel puţin 5 cîmpuri
şi are cel puţin 2 tipuri de date, iar cîmpul cheie trebuie să fie unic şi neordonat.
Să fie implementat şi dezvoltat programul prezentat în suportul de curs „Structuri de
date (în baza C++)”, autor dr.conf. Pereteatcu Sergiu
Să se implementeze cîteva metode de căutare în tabele şi să se efectueze căutarea după
cîmpul cheie din fişierul textual şi pentru fiecare metodă de efectuat următoarele:
- Să se analizeze lungimea medie teoretică şi lungimea practică de căutare.
- De descris algoritmul metodei de căutare pe paşi.
1 Metoda secvenţială de căutare
2 Metoda de căutarea în tabele neordonate structurate arborescent
2 Metoda binară de căutare
2 Metoda Fibonacci de căutare
2 Metoda de căutare în tabele ordonate
1 Un referat la tema „Metode de căutare”, prezentat în faţa colegilor
Descrtiere metode:
Metoda secvenţială de căutare
Cautarea secvenţială este unul dintre cei mai simpli algoritmi studiaţi. El urmăreşte să verifice
apartenenţa unui element la un şir de elemente de aceeaşi natură, în spetă a unui număr la un şir
de numere. Pentru aceasta se parcurge şirul de la un capăt la celălalt şi se compară numărul de
căutat cu fiecare număr din şir. În cazul în care s-a găsit corespondenţă (egalitate), un indicator
flag este poziţionat. La sfârşitul parcurgerii şirului, indicatorul ne va arăta dacă numărul căutat
aparţine sau nu şirului.
Metoda binară de căutare
Algoritmul de căutare binară oferă performanţe mai bune decât algoritmul de că utare secvenţială.
El funcţionează astfel: se compară numărul de căutat cu elementul aflat la mijlocul şirului (element
care se mai numeşte şi pivot). În cazul în care cele două elemente coincid căutarea s-a încheiat cu
succes. Dacă numărul de căutat este mai mare decât pivotul, se continua căutarea în aceeaşi
manieră în subşirul delimitat de pivot şi capătul şirului iniţial. Dacă numărul de căutat este mai
mic decât pivotul se continua căutarea în aceeaşi manieră
în subşirul delimitat de pivot şi începutul şirului iniţial.
Algoritmul prezentat se încadrează în clasa algoritmilor elaboraţi conform tehnicii de programare
Divide et Impera.
Unul din dezavantajele acestui algoritm este că şirul în care se face căutarea trebuie săfie iniţial
sortat.
Metoda de căutarea în tabele neordonate structurate arborescent
Căutarea unei valori este foarte asemănătoare cu operația adunare. Algoritmul de căutare
traversează copacul "în profunzime", alegând in mod adecvat parcurgerea, ca urmare a proprietăți
de căutare arborescente secompară valoarea fiecărui nod vizitat cu unul, căutăm. Algoritmul se
oprește în două cazuri:
-un nod cu o valoare necesară este găsit;
- algoritmul nu are nici o modalitate de a merge.
Algoritmul de căutare în detaliu:

Începând de la rădăcină ne deplasăm în direcţia maximală interschimbând elementele. Arborele


binar plin, adică, la care până la orice nivel există toate nodurile cu posibila excepţie pentru cele
mai drepte noduri ale ultimului nivel. Astfel de arbore poate fi reprezentat sub formă de vector.
Nodului cu indice i îi corespunde nodurile cu indicii 2*i+1 (fiul stâng, dacă 2*i+1<=n-1) şi
2*i+2 (fiul drept, dacă 2*i+2<=n-1).
Important de înţeles că nu creăm un arbore aparte, folosind formulele 2*i+1 şi 2*i+2,
prelucrămacest vector ca un arbore binar.
Un subarbore binar al arborelui binar care corespunde vectorului t[0]÷t[n-1] poate fi determinat
printr-o pereche de indici i şi j care corespund condiţiei (0<=i)&&(i<=j)&&(j≤n1), fii
elementului k, unde (i<=k)&&(k<=j), vor avea indicii 2*i+1 şi 2*i+2, dacă aceste valori nu întrec
j.

Metoda Fibonacci de căutare


Aceasta este găsită prin rezolvarea pentru cea mai mică valoare a lui n care face această inegalitate
adevărată: Fn> (ba) / toleranță, unde n este numărul Fibonacci din secvența {F0, F1, F2, ...}.
Conceptul de căutare Fibonacci implică plasarea două experimente între [a, b] , utilizând
raporturile de numere Fibonacci.
Pasul 1. Initializam toleranța, t> 0.
Pasul 2. Setați Fn> (ba) t ca cel mai mic Fn și definesc punctele / încercare

Pasul 3. Calculați f (x1) și f (x2)


Etapa 4. Compara f (x1) și f (x2)
(a.) Dacă f (x1) <f (x2), atunci noul interval este [x1, b]:
un devine x1 precedent b nu se schimbă
x1 devine x2 anterioară
n = n-1
Găsiti noul x2 folosind formula de la pasul 2.
(b). Dacă f (x1)> f (x2), atunci noul interval este [a, x2]:
a nu se schimbă
b devine x2 anterioară
x2 devine x1 precedent
n = n-1
Găsi noul x1 folosind formula de la pasul 2.
Etapa 5. Dacă lungimea noului interval de la pasul 4 este mai mică decât toleranța specificată,
opritorul. În caz contrar , du - te înapoi la Pasul 3.
Pasul 6. Estimarea x * ca punctul de mijloc al intervalului final și mașinei, f (x *), maximul
estimat al funcției.
Codul programului:
#include <cstdlib>
#include <cstdlib>
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <string>
#include<windows.h>
#include <stdlib.h>
using namespace std;

class elem {
public:
virtual int fscanf_el(FILE * f) = 0;
virtual int show(const char * opening, const char * ending) = 0;
virtual int free() = 0;

int operator>(elem &) {


error("Error should overide operator \">\"!\n");
return 0;
}

int operator<(elem &) {


error("Error should overide operator \"<\"!\n");
return 0;
}

int operator>=(elem &) {


error("Error should overide operator \">=\"!\n");
return 0;
}

int operator<=(elem &) {


error("Error should overide operator \"<=\"!\n");
return 0;
}

int operator==(elem &) {


error("Error should overide operator \"==\"!\n");
return 0;
}

int operator!=(elem &) {


error("Error should overide operator \"!=\"!\n");
return 0;
}
protected:

void error(char * message) {


cout << message;
cout << "press any key to fin....\n";
cin.get();
;
exit(1);
}
};

class MobiasBanca {
public:
int id;
char prenume[20];
char nume[20];
char functia[20];
char oras[20];
long tel;
int st;
int dr;

MobiasBanca() {
id = 0;
strcpy(prenume, "");
strcpy(nume, "");
strcpy(functia, "");
strcpy(oras, "");
tel = 0;
st = -1;
dr = -1;
}

void setId(int i) {
id = i;
}

void setPrenume(char* n) {
strcpy(prenume, n);
}

void setNume(char* a) {
strcpy(nume, a);
}

void setFunctia(char* b) {
strcpy(functia, b);
}

void setOras(char* d) {
strcpy(oras, d);
}

void setTel(long j) {
tel = j;
}

int getId() {
return id;
}
int set_st(int new_st) {
st = new_st;
return st;
}

int get_st() {
return st;
}

int set_dr(int new_dr) {


dr = new_dr;
return dr;
}

int get_dr() {
return dr;
}

char* getPrenume() {
return prenume;
}

char* getNume() {
return nume;
}

int getTel() {
return tel;
}

char* getFunctia() {
return functia;
}

char* getOras() {
return oras;
}

int fscanf_el(FILE * f) {
return fscanf(f, "%i %s %s %s %s %li", &id, prenume, nume, functia, oras, &tel);
}

void virtual show() {


cout << id << " " << prenume << " " << nume << " " << functia << " " << oras << " " << tel << endl;
}

virtual int free() {


return id == 0;
}

int operator>(MobiasBanca &e2) {


return (this->id > e2.id);
}
int operator<(MobiasBanca &e2) {
return (this->id < e2.id);
}

int operator<=(MobiasBanca &e2) {


return (this->id <= e2.id);
}

int operator>=(MobiasBanca &e2) {


return (this->id >= e2.id);
}

int operator==(MobiasBanca &e2) {


return (this->id == e2.id);
}

int operator!=(MobiasBanca &e2) {


return (this->id != e2.id);
}
};

template <class el> class tabel {


protected:
int n;
el t[200];
public:

tabel() {
n = 0;
}
tabel(char * file);
void search(int c);
void searchbin(int c);
int fib_search(el initial);
int searchtree(MobiasBanca tmp);
void createtree();
void killtree();
void sort();

void show(const char *opening, const char *ending);

protected:

void error(char *message) {


cout << message;
cout << "press any key to finish....\n";
cin.get();
;
exit(1);
}
};

template
<class el>
tabel<el>::tabel(char * file) {
FILE *pf;
pf = fopen(file, "rt");
n = 0;
while (!feof(pf))
if (t[n].fscanf_el(pf) > 0)
n++;
fclose(pf);
}

template
<class el>
void tabel<el>::search(int c) {
int position = -1, a, j;

for (int i = 0; (position == -1)&&(i < n); i++) {


a = t[i].getId();
;
if (c == a) {
position = i;
t[i].show();
}
}
if (position == -1) cout << "\nNu exista!";
else {
cout << "\nLungimea practica de cautare:" << position;
cout << "\nLungimea teoretica de cautare:" << n / 2;
}
}

template
<class el>
int tabel<el>::fib_search(el initial) {
int position = -1, contor = 0, i = 0, q = 0, p = 0;
double durata;
int fib[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765};
for (int j = 0;; j++) {
if (i > n) {
i = fib[j - 2];
p = fib[j - 3];
q = fib[j - 4];
break;
} else i = fib[j];
}
while (2 < 3) {
contor++;
if (initial == t[i]) {
position = i;
break;
}
if (initial < t[i]) {
if (q == 0) break;
else {
int v = p;
i = i - q;
p = q;
q = v - q;
}
}
if (initial > t[i]) {
if (p == 1) break;
else {
i = i + q;
p = p - q;
q = q - p;
}
}
}
if (position == -1) {
cout << endl;
cout << "Error!Error!" << endl;
} else {
cout << endl;
t[position].show();
cout << endl << "Lungimea practica de cautare:" << " " << contor << endl;
float caut;
caut = log(n) / log(2);
cout << "Lungimea teoretica de cautare:" << " " << caut << endl;
}
return position;
}

template
<class el>
void tabel<el>::show(const char *opening, const char *ending) {
cout << opening;
for (int i = 0; i < n; i++) {
t[i].show();
if (i % 20 == 0 && i != 0) {
cout << "\n" << "Tasteaza pentru a vedea tot...";
cin.get();
system("clr");
}
cout << ending;
cout << "\n ";
}
}

template
<class el>
void tabel<el>::sort() {
int j, count = 0;
el aux;
for (int i = 0; i < n - 1; i++)
for (j = i; j < n; j++) {
if (t[i].getId() > t[j].getId()) {
aux = t[i];
t[i] = t[j];
t[j] = aux;
count++;
}
}
cout << "Sortare finisata!" << endl;
cin.get();
;
}

template
<class el>
void tabel<el>::searchbin(int c) {
if (!n) {
cout << "ERROR! Introduceti datele";
cin.get();
;
return;
}
int s = 0, f = n - 1, count = 1, j;
int m = (s + f) / 2;

while ((c != t[m].getId())&&(s <= f)) {


count++;
if (t[m].getId() > c) {
f = m - 1;
} else {
s = m + 1;
}
m = (s + f) / 2;
}
if (s <= f) {
t[m].show();
cout << "\nLungimea practica de cautare:" << " " << count;
cout << "\nLungimea teoretica de cautare:" << " " << log(n) / log(2);
} else {
cout << "\n Nu exista inscrieri!";
}
}

template
<class el>
void tabel<el>::createtree() {
for (int i = 1; i < n; i++) {
int forw = 1, j = 0;
while (forw) {
if (t[i] < t[j]) {
if (t[j].get_st() == -1) {
t[j].set_st(i);
forw = 0;
} else
j = t[j].get_st();
} else
if (t[i] > t[j]) {
if (t[j].get_dr() == -1) {
t[j].set_dr(i);
forw = 0;
}
j = t[j].get_dr();
}
}
}
}

template
<class el>
void tabel<el>::killtree() {
for (int i = 0; i < n; i++) {
t[i].set_st(-1);
t[i].set_dr(-1);
}
}

template
<class el>
int tabel<el>::searchtree(MobiasBanca tmp) {
int i = 0, count = 0, forw = 1;
while (forw) {
if (tmp == t[i]) {
t[i].show();
cout << t[i].st << " " << t[i].dr << endl;
cout << "Lungimea practica de cautare:" << count << endl;
cout << "Lungimea teoretica MAX de cautare:" << n / 2 << endl;
cout << "Lungimea teoretica MIN de cautare:" << log(n) / log(2.0)*2.0;
forw = 0;
} else {
if (tmp < t[i])
i = t[i].get_st();
else
i = t[i].get_dr();
if (i == -1) {
forw = 0;
cout << "Elementul nu a fost gasit" << endl;
}
}
count++;
}
return 0;
}

int main() {
system("clr");
MobiasBanca pl, tmp;
tabel <MobiasBanca> gr("D:\\oleg.txt");
char ch, c;
int iden;

do {
system("clr");
cout << "Menu:" << endl;
cout << "*****************************************" << endl;
cout << "0)Avisare tabel" << endl;
cout << "1)Metoda secventiala" << endl;
cout << "2)Metoda arborescenta" << endl;
cout << "3)Sortare tabel" << endl;
cout << "4)Metoda binara" << endl;
cout << "5)Metoda fibonacci" << endl;
cout << "6)End" << endl;
c = cin.get();
;
switch (c) {
case '0':
ch = 'n';
while (ch != 'y') {
system("clr");
gr.show("Continutul tabelului:\n", " ");
cout << endl << "Atit?(Y/N)";
ch = cin.get();
;
}
break;
case '1':
ch = 'n';
while (ch != 'y') {
system("clr");
cout << "Introduceti id de cautare:" << endl;
cin>>iden;
cout << endl;
gr.search(iden);
cout << endl;
cout << endl << "Atit?(Y/N)";
ch = cin.get();
;
}
break;
case '2':
ch = 'n';
while (ch != 'y') {
system("clr");
cout << "Introduceti id de cautare:" << endl;
cin>>iden;
cout << endl;
tmp.setId(iden);
gr.createtree();
gr.searchtree(tmp);
cout << endl;
cout << endl << "Atit?(Y/N)";
gr.killtree();
ch = cin.get();
;
}
break;
case '3':
system("clr");
gr.sort();
cin.get();
;
break;
case '4':
ch = 'n';
while (ch != 'y') {
system("clr");
cout << "Introduceti id de cautare:" << endl;
cin>>iden;
cout << endl;
gr.searchbin(iden);
cout << endl;
cout << endl << "Atit?(Y/N)";
ch = cin.get();
;
}
break;
case '5':
ch = 'n';
while (ch != 'y') {
system("clr");
cout << "Introduceti id de cautare:" << endl;
cin >> pl.id;
cout << endl;
if (gr.fib_search(pl) == -1) cout << endl << "Eroare! Parcurgeti sortarea!" << endl;
cin.ignore();
cout << endl;
cout << endl << "Atit?(Y/N)";
ch = cin.get();
;
}
break;
}
} while (c != '6');
return 0;
}

Fiierul .txt cu 50 de înregistrări neordonate după cod:


1254 Ridha Tekaia CEO Chisnau 22812101
3548 Stela Ciobanu Secretar Chisnau 22812105
2848 Elena Guzun Director Chisnau 22812442
3508 Filip Kotora Retail Chisnau 22812103
1294 Damien Granier Chief Chisnau 22812104
9547 Andrei Suruceanu Director Chisnau 22812582
4848 Dumitru Cucos Contabil Chisnau 22812580
9477 Ludmila Olarescu Contabil Chisnau 22812395
6148 Cristian Rotaru Sef Chisnau 22812399
1548 Victor Padure Director Chisnau 22812679
7544 Ala Ionel Director Chisnau 22812754
3654 Iurie Iurco Director Chisnau 22812299
1202 Elena Gorenco Director Chisnau 22812229
8745 Petru Delinschi Director Chisnau 22812810
2151 Mariana Apostu Director Chisnau 22812811
3544 Margareta Betiu Director Chisnau 22812255
4515 Svetlana Pelin Director Chisnau 22812202
5144 Alexandru Gutu DirFil Chisnau 22812384
5471 Dumitru Popa DirFil Chisnau 22812615
6484 Valentin Nuca DirFil Chisnau 22812753
7554 Serghei Codrean DirFil Chisnau 22812712
2222 Alexandr Hovanschi DirFil Chisnau 22812647
9595 Veaceslav Bologan DirFil Chisnau 22812204
3547 Radu Jechiu DirFil Floresti 26522172
6544 Nadejda Stratenco DirFil Chisnau 22812825
9592 Alexandru Danuta DirFil Floresti 23622150
3215 Diana Pranitchi DirFil Chisnau 22812586
1554 Tatiana Maximov Director Chisnau 22812307
2445 Igor Ciobanu DirFil Floresti 23122199
3544 Elena Sadovschi Director Balti 23122199
6542 Igor Chisca DirFil Balti 24622673
1452 Nadejda Strechii DirFil Balti 23532398
3977 Hatuna Maximciuc DirFil Balti 29823035
7551 Nicolae Sandu DirFil Chisnau 22812125
8486 Olga Tarasiuc DirFil Chisnau 22812620
3444 Petru Arama DirFil Hincesti 26920582
4541 Ludmila Savca DirFil Drochia 25220188
4843 Violetta Chifa DirFil Chisnau 22812171
1211 Viorica Rusu DirFil Chisnau 22812188
2254 Serghei Revenco DirFil Soroca 23068009
3511 Iuri Kann DirFil Chisnau 22812121
3002 Dan Morcov DirFil Chisnau 22812630
5001 Corina Bordei DirFil Chisnau 22812660
2000 Galina Railean DirFil Chisnau 22812155
3550 Nina Doaga DirFil Chisnau 22812688
3611 Serghei Tcacenco DirFil Chisnau 22812148
8200 Nadejda Radu DirFil Ialoveni 26822260
9200 Ala Tatarenco DirFil Ialoveni 23120434
1180 Dmitrii Moldovanu DirFil Causeni 24322259
7110 Maria Golban DirFil Chisnau 22812801
1250 Tatiana Barladean DirFil Chisnau 22812670
4833 Natalia BuranPavlova DirFil Singerei 26268001
1877 Sergiu Ciuvalschi DirFil Chisnau 22812682
7122 Ion Leanca DirFil Chisnau 22812722
7720 Viorica Plescan DirFil Chisnau 22812738
7777 Octavian Butuleac DirFil Chisnau 22812730
8888 Aliona Apostol DirFil Chisnau 22812766
2224 Natalia Chiciuc DirFil CeadirLunga 29165001
3559 Angela Bolun DirFil Chisnau 22812777
1024 Doina Malai DirFil Chisnau 22812791
3540 Angela Crestian Bum 23159098
1113 Serghei Rusu DirFil Cahul 23193969
5177 Viorel Paladii DirFil Floresti 25073013
1020 Alexei Goian DirFil Rezina 25468002
1808 Oleg Coguteac DirFil Chisnau 22812816
4422 Daria Babin DirFil Falesti 25924140
6655 Sergiu Roibu DirFil Chisnau 22812916
9911 Natalia Chiciuc DirFil Chisnau 22812265

Rezultatul:

Căutarea Secventiala

Metoda arborescenta
Căutarea Binară
Căutarea Fibonacci

Concluzie:

Căutarea selectivă este căutarea caracteristică tabelelor neordonate,astfel ea este eficientă la un


număr mic de înregistrări,odată cu cre terea numărului de obiecte în tabel și cu atît eficiența ei
scade. Căutarea binară este mai eficientă în numărul mare de înregistrări , dar totuși nu la un număr
extrem de mare. Cea mai eficientă este căutarea Fibiacci în cazul tabelelor cu un număr mare de
elemente. În tabel sunt înscrise toate datele calculate la metodele de căutare.