Sunteți pe pagina 1din 11

Modul ASD Basic U1 L2: Tablouri liniare.

Șiruri de caractere

Unitatea 1: algoritmi și structuri de date elementare


Lecția 2: Tablouri liniare. Șiruri de caractere
Vei afla:
• Ce este o structură de date
• Ce proprietăți are un tablou unidimensional (liniar)
• Care este specificul utilizării tablourilor formate din caractere
• Care sunt cei mai des utilizați algoritmi pe tablouri și șiruri de caractere

Ce este o structură de date?

Utilizarea variabilelor și a tipuri de date simple presupune relația între acestea determinată de
principiul o variabilă – o valoare. Acesta devine impracticabil în cazul utilizării unui număr mare de
variabile.
În problemele care impun utilizarea unui număr mare de date sunt folosite structurile de date.

Structura de date este o colecție de valori (date), relații între ele și operații, care por fi aplicate
asupra datelor.

La fel ca variabila simplă structura de date este identificată de numele său.

Structurile de date sunt clasificate după diverse caracteristici: omogene – neomogene, cu acces direct
– secvențial, statice – dinamice. Caracteristicile sunt antagoniste doar în pereche, în sens larg ele se pot
combina, altfel vorbind pot exista structuri omogene statice cu acces direct, structuri dinamice cu acces
secvențial și tot așa.
Dacă toate elementele structurii de date au același tip (de exemplu numere întregi sau caractere)
structura este omogenă, dacă însă elementele ei sunt date de diverse tipuri (numere și caractere, sau
caractere și valori de tip logic) structura este considerată neomogenă.
Dacă numărul de elemente care se conțin în structura de date nu poate fi modificat pe perioada
existenței acesteia, structura se numește statică. Dacă însă structura permite adăugarea / lichidarea
elementelor – se numește dinamică.
Structura de date este considerată ordonată, dacă între elementele ei este definită ordinea de
parcurgere. În calitate de exemplu poate fi adus un șir numeric în care pentru orice element (cu excepția
primului și ultimului) este definit elementul precedent și elementul următor. Un indicator important al
ordonării structurii de date este de asemenea prezența indicelui elementului – numărul lui de ordine.
Cele mai simple structuri de date sunt tablourile unidimensionale. De multe ori ele mai sunt numite
și tablouri liniare.
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Proprietățile tabloului unidimensional

Tabloul reprezintă o structură de date statică, ceea ce înseamnă că tabloul are un număr fix de
elemente – număr care nu se modifică tot timpul
cât tabloul există.
Unidimensional este un indicator al modului
de organizare – elementele sunt amplasate liniar,
unul după altul și identificate cu ajutorul unui
singur indice, care indică și numărul de ordine.
Formulele de calcul a poziției elementului în tabolurile din limbajele C și C++ impun numerotarea
elementelor în tablouri începând cu indicele 0.
Tipul elementelor tabloului unidimensional poate fi oricare dintre tipurile simple ale limbajului de
programare.
Numele tabloului poate fi orice identificator a cărui structură corespunde regulilor de formare a
identificatorilor în limbajul de programare utilizat.

Declararea tabloului unidimensional

Limbajele C și C++ oferă o mulțime de variante diferite de declarare și inițializare a tablourilor. În cadrul
cursului vom folosi cel mai simplu model de declarare a tabloului unidimensional:
<tip elemente tablou> <nume tablou> [<numar elemente>];

int vot[8]; Este declarat un tablou cu 8 elemente, a căror valori pot fi numere întregi.
Elementele vor avea indicii de la 0 la 7 inclusiv. Numele tabloului este vot.
float salariu[12]; Este declarat un tablou cu 12 de elemente, a căror valor pot fi numere reale.
Elementele vor avea indicii de la 0 la 11 inclusiv. Numele tabloului este
salariu.
char nume[30] Este declarat un tablou cu 30 de elemente, a căror valori pot fi caractere.
Elementele vor avea indicii de la 0 la 29 inclusiv. Numele tabloului este nume.
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Accesarea elementelor tabloului unidimensional

Fie declarat tabloul Zet:


int Zet[10];
int i, j;

După declarare, apariția în textul programului a


numele tabloului, însoțit de valoarea unui indice indică
valoarea elementului din poziția marcată de acel
indice. Astfel Zet[1] va indica valoarea celui de al doilea element al tabloului, Zet[i] va indica valoarea
elementului, a cărui indice coincide cu valoarea variabilei i și tot așa.

Atribuirea valorilor elementelor tabloului

Valorile elementelor tabloului pot fi atribuite direct, la declarare:


<tip elemente> <nume> [<numar elemente>] = {val0, val1, ..., valn-1} ;

Valorile enumerate vor fi atribuite consecutiv elementelor tabloului de la stânga spre dreapta. Dacă
numărul valorilor enumerate este mai mic decât cel al elementelor, ultimele elemente din tablou nu vor
primi valori implicite.
Exemple
int c[6] = {10, 8, 13, 7, 46, 32}; // vor primi valori toate 6 elemente
float d[4] = {4.4, 2.8} // vor primi valori primele două elemente
char z[10] = {’b’, ’e’, ’t’}; // vor primi valori primele 3 elemente

Pentru atribuirea valorilor elementelor tabloului pot fi folosite funcțiile de introducere a datelor:
Un tablou, declarat static, are un număr fix de elemente. Numărul de elemente utilizate poate fi mai
mic decât dimensiunea tabloului. Pentru a nu folosi elemente în exces se utilizează o variabilă
suplimentară (de obicei este notată cu n) care corespunde numărului real de elemente ale tabloului în
instanța curentă a programului.
În exemplele care urmează vom considera că avem declarat tabloul a cu un număr suficient de
elemente de tip întreg, fie int a[100]. Vom folosi instrumentarul limbajului C++:
cout <<”Nr elemente : ”; cin >> n;
for (int i = 0; i < n; i++)
{
cout << ”Element : ” << i; cin >> a[i];
}
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Sau varianta mai compactă, fără mesaje auxiliare:


cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];

Observăm, că fiecare valoarea a elementului tabloului este citită separat, ca o entitate aparte.

Afişarea valorilor elementelor tabloului

O altă operație, care poate fi realizată asupra unui tablou, este afișarea valorilor elementelor acestuia.
Vom considera în continuare, că numărul utilizate din tablou este n, și, desigur, n nu depășește
dimensiunea declarată a tabloului.
Deoarece fiecare element reprezintă o entitate aparte, va fi afișat separat. Prin urmare este necesară
repetarea de n ori a afișării unui element distinct:
for (int i = 0; i < n; i++) cout << a[i] << ” ”;

Specificul utilizării tablourilor de caractere

Pentru a simplifica introducerea secvențelor de caractere, care apoi ar forma un tot întreg (cuvânt,
propoziție, text, etc.) tablourile unidimensionale a căror elemente au tipul char au fost separate într-o
categorie aparte, numită sir de caractere.

Șir de caractere - tablou unidimensional de caractere, care se termină cu un caracter NUL: '\0'.

NUL - Caracter care semnifică ”nimic”. Caracterul nul nu se afișează, nu ocupă spațiu pe ecran sau
la tipar, nu produce nici o acțiune. Caracterul nul însă ocupă spațiu în memorie. Este identificat în
tabelul ASCII de codul 0. Notația folosită: '\0'.

Șirurile de caractere combină proprietăți ale variabileleor simple cum ar fi citirea și afișarea prin o
singură instrucțiune cu proprietăți ale tablourilor, cum ar fi accesul direct la fiecare caracter.

Declararea șirurilor de caractere

Șirurile de caractere se declară într-un program C / C++ la fel ca tablourile:


char <nume sir de caractere>[<numar caractere in sir>];

Caracterul NUL este parte a șirului de caractere. La citire ’\0’ este adăugat în mod automat la sfârșitul
șirului introdus, atât în C cât și în C++.
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Șirurile de caractere mai pot fi declarate în limbajul C++ utilizând tipul de date string:
string <nume sir de caractere>;
În cazul utilizării datelor string se recomandă includerea în program a librăriei <string>

Citirea și afișarea șirurilor de caractere

C++ permite citirea șirurilor de caractere care nu conțin spații cu ajutorul obiectului cin:
cin >> <nume sir de caractere>;

Pentru afișarea unui șir de caractere în limbajul C++ se folosește obiectul cout
cout << <sir de caractere>;

Algoritmi pe tablouri și șiruri de caractere

Ciurul lui Eratostene

Ciurul lui Eratostene este un algoritm clasic pentru determinarea numerelor prime din diapazonul de
la 1 până la o valoare n dată.
Algoritmul pentru implementarea sa manuală, este descris în felul următor:
Pas 1. Se formează șirul S de numere consecutive: 2, 3, 4, ..., n-1, n.
Pas 2. Se identifică primul element diferit de 0 din S. Fie acesta are valoarea x. x este adăugat în lista
de numere prime L. Apoi, x împreună cu toți multiplii săi din șirul S sunt înlocuiți cu 0.
Pas 3. Dacă S conține elemente diferite de 0, se revine la Pas 2. Altfel se trece la pas 4:
Pas 4. Se afișează lista de numere prime L. SFÂRȘIT.

Exemplu:
Să se determine numerele prime din diapazonul 2, ... , 10.
S = {2, 3, 4, 5, 6, 7, 8, 9, 10}
L = {}
Primul element diferit de 0 din S este 2.
2 se adaugă în L: L = {2}
2 și multiplii lui sunt înlocuiți cu 0 în S: S = {0, 3, 0, 5, 0, 7, 0, 9, 0}
S conține elemente nenule. Repetăm Pasul 2.
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Primul element diferit de 0 din S este 3.


3 se adaugă în L: L = {2, 3}
3 și multiplii lui sunt înlocuiți cu 0 în S: S = {0, 0, 0, 5, 0, 7, 0, 0, 0}
S conține elemente nenule. Repetăm Pasul 2.
Primul element diferit de 0 din S este 5.
3 se adaugă în L: L = {2, 3, 5}
5 și multiplii lui sunt înlocuiți cu 0 în S: S = {0, 0, 0, 0, 0, 7, 0, 0, 0}
S conține elemente nenule. Repetăm Pasul 2.
Primul element diferit de 0 din S este 7.
7 se adaugă în L: L = {2, 3, 5, 7}
7 și multiplii lui sunt înlocuiți cu 0 în S: S = {0, 0, 0, 0, 0, 0, 0, 0, 0}
S nu mai conține elemente nenule. Numerele prime între 2 și 10 sunt: 2, 3, 5, 7.
O rezolvare a problemei în formă de program elimină toate calculele ”de mână” și posibilele erori.
Pentru a obține această implementare, mai întâi vom separa operațiile elementare din care sunt formați
pașii algoritmului:
Fie n – extremitatea dreaptă a diapazonului de căutare a numerelor prime.
Pas 1. Inițializăm tabloul S cu n + 1 elemente cu valorile 0, 0, 2, 3, 4, ... , n. i – indicele primului element
nenul din tablou va fi setat la 2 (i  2 ). k - indicele elementului de adăugat în tabloul numerelor prime L
va fi setat la 0: (k  0)
Pas 2: Cât timp s[i] = 0 și nu s-a atins valoarea n+1 (i ≤ n) trecem la următorul i (i++).
Dacă (i ≤ n) atunci

x s[i]; // selectarea numărului ”activ”


L[k] = x; k++; // adăugarea numărului în tabloul numerelor prime

Pentru toți j de la i la n se verifică: dacă (s[j] % x == 0) atunci s[j]  0.


// excluderea multiplilor x din S
În caz contrar:
Pentru j de la 0 la k-1 afișăm L[j]. STOP.

După stabilirea restricțiilor pentru valoarea n putem transforma algoritmul în program.


Fie n nu depășește 1000.
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Liniile 1 – 6 conțin directivele de includere a librăriilor (linia


1), priorități de utilizare a spațiului de nume pentru funcții (linia
2) definiții (linia 4), declarații de variabile(linia 6)

Introducerea datelor inițiale și inițializarea valorilor


structurilor de date sunt realizate în liniile 10 – 11.

Căutarea repetată a primului element nenul și operațiile


asupra acestuia sunt realizate în liniile 13 – 18:

• repetarea consecutivă a verificării valorii curente (linia 13)


• verificarea valorii curente (nul / nenul) (linia 14)
• adăugarea valorii nenule în lista numerelor prime și
actualizarea numărului de elemente în listă( linia 16)
• zerografierea în șirul inițial a elementului cu valoarea i și a
multiplilor acestuia
În final, este efectuată afișarea listei de numere prime(linia 20)
Exemplu:

Verificarea proprietății de palindrom a unui șir de caractere

Palindrom este numită o secvență de simboluri care are proprietatea de a se citi la fel de la stânga la
dreapta și de la dreapta la stânga.

Exemple de secvențe – palindrom sunt:

Formate din un singur cuvânt: caiac, cojoc, etalate, calabalac

Propoziții palindrom: Ele ne seduc cu desenele

Enunțul problemei:

Problema se formulează extrem de simplu: fiind dat un șir de caractere, să se determine dacă acesta
posedă proprietatea de palindrom sau nu.

Intrare: din inputul standard (de la tastatură) se citește șirul de caractere în studiu.

Ieșire: În outputul standard (ecran) se afișează mesajul ”Palindrom” dacă șirul de caractere în studiu
este un palindrom și NON-palindrom în caz contrar.

Restricții: lungimea șirului de caractere nu va depăși 100. Șirul nu va conține spații.


Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Rezolvare: este ușor de observat că proprietatea de palindrom presupune o simetrie a valorișor din șir
față de caracterul din mijlocul șirului (dacă șirul conține un număr impar de caractere) sau față de axa
imaginară care separă șirul în jumătăți egale ca lungime (dacă șirul conține un număr par de caractere)

Prin urmare este suficient să verificăm perechile simetrice (după indici) de caractere. Putem verifica
prezența simetriei tuturor perechilor de caractere sau, mai simplu, putem căuta o pereche de caractere,
poziționate simetric, dar având valori diferite. Dacă există cel puțin o asemenea pereche șirul nu mai este
palindrom. Dacă o asemenea pereche NU există , șirul este palindrom!
O schemă simplă ne sugerează formula pentru formarea perechilor de caractere amplasate simetric.
Pentru un șir cu n elemente avem perechile simetrice:

Din schemă rezultă:

a[0] formează o pereche simetrică cu a[n - 1]

a[1] formează o pereche simetrică cu a[n - 2]

...

a[i] formează o pereche simetrică cu a[n – i - 1]

Valoarea i va varia de la 0 la n/2 -1.

Prin urmare, putem formula următorul algoritm:

Fie șirul a, format din n caractere, având indicii de la 0 la n-1.

Pas 1. flag  0.

Pas 2. Pentru valorile consecutive i de la 0 la n/2 -1 repetăm: dacă a[i]  a[n-i-1] atunci flag  1
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Pas 3. Dacă flag = 0 șirul a este palindrom, în caz contrar – nu. STOP.

Implementarea acestui algoritm în limbajul C++ este extrem de simplă:


Tradițional, programul începe cu includerea librăriilor,
stabilirea priorităților spațiului de nume, declararea variabilelor.
(liniile 1, 2, 4-5)

Suplimentar, descriem o funcție proprie care ne permite să


calculăm lungimea unui șir de caractere, fără a apela la librăriile
care conțin funcții similare: liniile (7 - 13). Acținunea descrisă în
funcție este una elementară: numărarea caracterelor până la
întâlnirea caracterului care indică sfârșitul șirului transmis în
calitate de parametru (liniile 9 - 10) și returnarea rezultatului (linia
12).

Funcția main() (liniile 15 - 26) corespunde acțiunilor descrise


pe pași în algoritm:

se citește șirul de caractere (linia 17)

Exemple: se determină lungimea lui (linia 18)

se verifică perechile de caractere amplasate simetric față de


mijlocul șirului (linia 19) până la apariția uneia dintre două situații:
este detectată o pereche de caractere diferite (linia 20) sau
epuizarea perechilor (linia 19). În primul caz verificările ulterioare
nu mai sunt necesare, prin urmare pot fi anulate (instrucțiunea
break)

în funcție de valoarea variabilei flag se afișează mesajul


corespunzător cerințelor problemei (liniile 22, 23)
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

Linkuri utile:

1. Array https://www.geeksforgeeks.org/arrays-in-c-cpp/
2. Array of char http://www.cplusplus.com/doc/tutorial/ntcs/
3. Ciurul lui Eratostene https://www.infoarena.ro/ciurul-lui-eratostene
4. Palindrom https://ro.wikipedia.org/wiki/Palindrom
Modul ASD Basic U1 L2: Tablouri liniare. Șiruri de caractere

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