Sunteți pe pagina 1din 6

ALGORITMI DE CĂUTARE ÎN VECTORI

Formularea temei. Să se scrie funcţii care să returneze numărul de apariţii ale unui
scalar într-un vector şi indicii acestora. De asemenea, să se verifice existenţa într-un vector
a unei secvenţe date de elemente.

Noţiuni teoretice. Un tablou este o structură de date având un număr fix de


elemente de acelaşi tip, memorate unul după altul într-o zonă continuă de memorie.
Adresarea unei componente a unui tablou se face prin indice. Numerotarea începe
implicit, atât în limbajul C cât şi în MathCAD, de la 0. Astfel, elementele unui vector, v , cu
10 componente, pot fi adresate prin v[0] , v[1], ..., v[9] , iar cele ale unei matrici, a , de 5 linii
şi 6 coloane, cu a[0][0], ..., a[4][5] . Scrierea indicelui între paranteze este specifică
limbajului C, în MathCAD utilizându-se pentru indexare operatorul Subscript.
În MathCAD, valoarea de pornire pentru numerotarea componentelor unui tablou
poate fi gestionată prin intermediul parametrului ORIGIN, căruia i se pot atribui alte valori
decât cea implicită, 0. Trebuie să se facă distincţie între variabila numită „a indice i” - ai ,
obţinută tastând litera „a”, apoi „.”, apoi „i”, şi componenta de indice i a vectorului a (caz în
care se tastează „a”, apoi Subscript, apoi „i”).
În limbajul C nu se pot declara variabile tablou cu număr variabil de componente.
Dacă apare necesitatea tratării unei variabile tablou al cărei număr de componente nu se
cunoaşte de la început, se rezervă un număr maxim de spaţii de memorie, unele dintre ele
rămânând neutilizate după execuţia algoritmului. Pe de altă parte, dacă pe parcursul
execuţiei programului este necesară alocarea de noi spaţii de memorie, se utilizează alocarea
dinamică.

Exerciţiul 1. Să se scrie o funcţie care să verifice dacă un scalar dat se regăseşte


într-un vector cunoscut.

Propunere de algoritm. Se iniţializează cu valoarea 0 o variabilă de test. Vectorul


se parcurge cu o instrucţiune repetitivă, verificându-se egalitatea dintre scalar şi elementul
vectorului adresat la pasul respectiv. Verificarea condiţiei determină modificarea valorii
variabilei test, iniţial nulă, într-o valoare diferită de 0, de exemplu 1, determinând ieşirea din
ciclu. Afişarea datelor de ieşire se face în funcţie de valoarea variabilei test.

seek ( u , a) := test ← 0
for i ∈ 0 .. length ( u ) − 1
if u a T
i v := ( 4 6 5 3 0 8 )
test ← 1 seek ( v , 3) = "Scalarul exista in vector"
break seek ( v , 9) = "Scalarul nu exista in vector"
"Scalarul exista in vector" if test
"Scalarul nu exista in vector" otherwise
44 7. Algoritmi de căutare în vectori

Parametrii formali ai funcţiei seek sunt vectorul u şi scalarul a. Variabila de ciclare


pentru adresarea elementelor vectorului este i. Instrucţiunea break acţionează ieşirea din
ciclu (întreruperea parcurgerii vectorului) imediat ce se verifică egalitatea între a şi
elementul vectorului adresat la pasul respectiv.
Păstrând semnificaţia variabilelor, se propune o variantă de cod în limbaj C. Pentru
citirea şi afişarea vectorului a fost necesară introducerea unei variabile, n, care să memoreze
numărul său de elemente.

#include<stdio.h>
#include<conio.h>
main(){
int n,i,a,test=0,u[10];
printf(ʺIntroduceti nr de elem ale vct:ʺ);
scanf(ʺ%iʺ,&n);
for(i=0;i<n;i++){
printf(ʺIntroduceti elementul de index %i:ʺ,i);
scanf(ʺ%iʺ,&u[i]);}
printf(ʺAti introdus vectorul:\tʺ);
for(i=0;i<n;i++) printf(ʺ%i\tʺ,u[i]);
printf(ʺ\nIntroduceti scalarul:ʺ);scanf(ʺ%iʺ,&a);
for(i=0;i<n&&!test;i++)
if(u[i]==a)test=1;
if(test) printf(ʺScalarul exista in vectorʺ);
else printf(ʺScalarul nu exista in vectorʺ);
getch();}

Exerciţiul 2. Să se scrie o funcţie care să numere apariţiile unui scalar într-un


vector, ambele citite de la tastatură.

Propunere de algoritm. Codul este asemănător cu cel al aplicaţiei precedente, cu


deosebirea că este necesară parcurgerea integrală a vectorului. Variabila test se
incrementează la fiecare egalitate a scalarului cu elementul din vector adresat la pasul
respectiv. Ca dată de ieşire se va afişa valoarea variabilei test.

seek_nr ( u , a) := test ← 0 T
v := ( 4 3 5 3 0 8 )
for i ∈ 0 .. length ( u ) − 1
seek_nr ( v , 3) = 2
test ← test + 1 if u a
i seek_nr ( v , 9) = 0
test

Păstrând semnificaţia variabilelor, se scrie codul următor în limbaj C:

#include<stdio.h>
#include<conio.h>
main(){
int n,i,a,test=0,u[10];
printf(ʺIntroduceti nr de elemente ale vct:ʺ);
scanf(ʺ%iʺ,&n);
45 7. Algoritmi de căutare în vectori

for(i=0;i<n;i++){
printf(ʺIntroduceti elementul de index %i:ʺ,i);
scanf(ʺ%iʺ,&u[i]);}
printf(ʺAti introdus vectorul:\tʺ);
for(i=0;i<n;i++) printf(ʺ%i\tʺ,u[i]);
printf(ʺ\nIntroduceti scalarul:ʺ);scanf(ʺ%iʺ,&a);
for(i=0;i<n;i++)
if(u[i]==a)test++;
printf(ʺScalarul exista in vector de %i oriʺ,test);
getch();}

Exerciţiul 3. Să se scrie o funcţie care să caute o secvenţă de elemente dată într-un


vector introdus de la tastatură.

Propunere de algoritm. În cazul de faţă, concluzia afirmativă se trage numai după


verificarea a n egalităţi, unde n este numărul de elemente ale secvenţei. Mai mult, egalităţile
trebuie să se realizeze pentru poziţii consecutive din vector.

seek_vct ( u , v ) := for i ∈ 0 .. length ( u ) − length ( v )


test ← 0
for j ∈ 0 .. length ( v ) − 1
test ← test + 1 if u v
i+ j j
break if test length ( v )
"Se verifica aparitia" if test length ( v )
"Nu se verifica aparitia" otherwise

T T T
a := ( 4 2 8 6 4 9 ) b := ( 8 6 4 ) c := ( 8 7 )

seek_vct ( a , b ) = "Se verifica aparitia" seek_vct ( a , c) = "Nu se verifica aparitia

Se propune funcţia seek_vct cu parametri formali vectorul u, în care se face


căutarea şi vectorul v, secvenţa care se caută. Variabila test numără egalităţile realizate între
poziţii consecutive din vectorii u şi v. Dacă plecând de la o poziţie i din vectorul u se
realizează length(v) evenimente de egalitate, se iese din ciclu semnalându-se existenţa
secvenţei în vector.

Exerciţiul 4. Să se scrie o funcţie care să verifice existenţa secvenţei (m, n, *, p), cu


m, n, p citite de la tastatură, într-un vector dat. Caracterul * poate înlocui orice element.

Propunere de algoritm. Codul este asemănător cu cel de la exerciţiul precedent, cu


următoarele deosebiri:
• Nu este semnificativă numărarea evenimentelor de egalitate, deoarece caracterul *
poate genera egalitate sau nu.
• Egalităţile nu au loc pentru poziţii consecutive.
Se impune în consecinţă scrierea unei expresii care să verifice fiecare poziţie
cunoscută din secvenţă.
46 7. Algoritmi de căutare în vectori

seek_vct ( u , m, n , p ) := for i ∈ 0 .. length ( u ) − 4


test ← 0
test ← 1 if u ( i )(
m⋅ u
i+ 1 )(
n ⋅ u
i+ 3
p )
break if test
"Se verifica aparitia" if test
"Nu se verifica aparitia" otherwise

T T T
a := ( 4 2 8 6 4 9 ) b := ( 2 8 5 4 ) c := ( 8 6 5 9 )

seek_vct ( a , 2 , 8 , 4) = "Se verifica aparitia" seek_vct ( a , 8 , 6 , 9) = "Se verifica aparitia"


seek_vct ( a , 2 , 8 , 6) = "Nu se verifica aparitia"

Exerciţiul 5. Să se scrie o funcţie care să extragă dintr-un vector citit de la tastatură


elementele care satisfac o anumită condiţie.

Propunere de algoritm. Vectorul se parcurge cu o instrucţiune repetitivă în care


variabila de ciclare memorează, pe rând, indicii elementelor vectorului. Condiţia poate fi
dată ca funcţie de un scalar, care returnează 1 dacă scalarul o verifică şi 0 în caz contrar. Ea
se poate alege din lista următoare:
• Scalarul este număr prim.
• Scalarul este multiplu de 3 şi 5.
Elementele care verifică condiţia vor fi preluate într-un alt vector. Variabila care
memorează, pe rând, indicii elementelor acestuia, iniţializată cu 0, se incrementează la
fiecare verificare a condiţiei.

mltp( m) := 1 if ( mod( m, 3) 0) ⋅ ( mod( m, 5) 0) prim( a) := 1 if a 2


0 otherwise otherwise
s←0
extrag( u , cond ) := k←0
for i ∈ 2 .. a
for i ∈ 0 .. length ( u ) − 1
s ← s + 1 if ¬mod( a , i)
if cond u( i) break if s
v ←u ¬s
k i
k←k+ 1
v T
a := ( 15 13 10 30 7 9 )

 15   13 
extrag( a , mltp) =  extrag( a , prim) = 
 30  7

Funcţia extrag are ca parametri formali vectorul u, din care se face extragerea şi
condiţia cond ce trebuie verificată. Ea izolează elementele din u ce satisfac cond în
vectorul v, de indice k. Funcţiile mltp şi prim, cu parametru de apelare scalarul a, verifică
condiţiile propuse în formularea problemei, returnând 1 dacă argumentul le verifică şi 0 în
caz contrar. Ele vor înlocui parametrul formal cond în apelul funcţiei extrag.
47 7. Algoritmi de căutare în vectori

Exerciţiul 6. Să se scrie o funcţie care să localizeze prin indice apariţiile unui scalar
într-un vector, ambele citite de la tastatură.

Propunere de algoritm. Adresarea elementelor vectorului se face cu o instrucţiune


repetitivă. La verificarea egalităţii între scalar şi elementul vectorului adresat la pasul
respectiv, indicele acestuia este preluat într-un alt vector, al cărui indice se incrementează la
adăugarea unui nou element.

poz( u , a) := k←0
for i ∈ 0 .. length ( u ) − 1 T
m := ( 15 3 10 3 7 9 )
if u a
i
1
v ←i poz( m, 3) = 
k 3
k←k+ 1
v if IsArray ( v ) poz( m, 5) = "Nu se verifica aparitia"
"Nu se verifica aparitia" otherwise

Funcţia poz are ca parametri formali vectorul în care se face căutarea, u şi scalarul
care se caută, a. Valorile indicilor poziţiilor ce verifică condiţia sunt memorate în vectorul
v. Dacă acesta nu are nici un element, se afişează mesajul „Nu se verifică apariţia”.
De remarcat că datele de ieşire ale acestei funcţii sunt în dependenţă de valoarea
parametrului ORIGIN, exemplul de mai sus fiind realizat cu setări implicite.
Păstrând semnificaţia variabilelor, se scrie codul în limbaj C:

#include<stdio.h>
#include<conio.h>
main(){
int n,i,a,k=0,u[10];
printf(ʺIntroduceti nr de elem ale vct:ʺ);
scanf(ʺ%iʺ,&n);
for(i=0;i<n;i++){
printf(ʺIntroduceti elementul de index %i:ʺ,i);
scanf(ʺ%iʺ,&u[i]);}
printf(ʺAti introdus vectorul:\tʺ);
for(i=0;i<n;i++) printf(ʺ%i\tʺ,u[i]);
printf(ʺ\nIntroduceti scalarul:ʺ);scanf(ʺ%iʺ,&a);
printf(ʺScalarul %i apare pe pozitiile:\tʺ,a);
for(i=0;i<n;i++)
if(u[i]==a) printf(ʺ%i\tʺ,i);
getch();}

Exerciţiul 7. Să se scrie o funcţie care să returneze indicele apariţiei a n-a a


elementului m în vectorul u, cu m, n şi u citiţi de la dispozitivul de intrare.

Propunere de algoritm. Adresarea elementelor vectorului se face printr-o


instrucţiune repetitivă. Variabila locală s, iniţializată cu valoarea 0, se incrementează cu
48 7. Algoritmi de căutare în vectori

fiecare nouă apariţie. Variabilă, test, iniţializată de asemenea cu 0, îşi modifică valoarea în
momentul în care variabila s atinge valoarea cerută, n, determinând ieşirea din ciclu.

seek_apr ( u , m, n ) := s←0
test ← 0
for i ∈ 0 .. length ( u ) − 1
s ← s + 1 if u m
i
T
a := ( 5 3 8 7 5 5 4 )
if s n
test ← 1
break
i if test
"Aparitia cautata nu se verifica" otherwise
seek_apr ( a , 5 , 2) = 4 seek_apr ( a , 5 , 4) = "Aparitia cautata nu se verifica"
seek_apr ( a , 5 , 1) = 0 seek_apr ( a , 6 , 2) = "Aparitia cautata nu se verifica"

Păstrând semnificaţia variabilelor se dă codul următor în limbaj C:

#include<stdio.h>
#include<conio.h>
main(){
int nr,i,m,n,u[10],test=0,s=0;
printf(ʺIntroduceti nr de elem ale vct:ʺ);
scanf(ʺ%iʺ,&nr);
for(i=0;i<nr;i++){
printf(ʺIntroduceti elementul de index %i:ʺ,i);
scanf(ʺ%iʺ,&u[i]);}
printf(ʺAti introdus vectorul:\tʺ);
for(i=0;i<nr;i++) printf(ʺ%i\tʺ,u[i]);
printf(ʺ\nIntroduceti scalarul:ʺ);scanf(ʺ%iʺ,&m);
printf(ʺA cata aparitie se cauta?ʺ);scanf(ʺ%iʺ,&n);
for(i=0;i<nr&&!test;i++)
{if(u[i]==m) s++;
if (s==n) test=1;}
if(test) printf(ʺIndicele cautat este %iʺ,i-1);
else printf(ʺAparitia cautata nu se verificaʺ);
getch();}

Temă de lucru

Se dau un vector şi un scalar. Să se afişeze:


• cel mai mare element din vector mai mic decât scalarul dat;
• cel mai mic element din vector mai mare decât scalarul dat.

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