Sunteți pe pagina 1din 299

2

Prefaţă

Progresele tehnologice în domeniul informaticii au condus la creşterea puterii de cal- cul şi a memoriei calculatoarelor electronice, la ieftinirea acestor calculatoare, per- miţând abordarea unor probleme extrem de complexe, din toate sferele activităţii umane. Calculatorul a devenit un instrument indispensabil pentru viaţa omului mo- dern. Penetrarea Internetului şi a accesului la resursele informatice mondiale, lărgirea considerabilă a spectrului de aplicaţii a contribuit şi contribuie la impunerea calcula- torului ca instrument de lucru vital în activitatea omului. În consecinţă, cerinţa de noi programe în toate domeniile activităţii umane a crescut mereu.

De aceea, se impune tot mai pregnant creşterea importanţei metodologiilor de realizare a produselor program, necesitatea unei instruiri corespunzătoare a noilor

generaţii de specialişti şi de utilizatori ai calculatoarelor. În formarea specialiştilor

în informatică este importantă dobândirea unor cunoştinţe şi deprinderi de a realiza

produse program de o complexitate variată, care să satisfacă cerinţele beneficiarului. Pentru aceasta este necesară respectarea unei discipline de lucru şi cunoaşterea unei metodologii adecvate de proiectare şi realizare a acestor produse software. În trecutul nu prea îndepărtat, în activitatea de instruire a specialiştilor în informatică s-a pus un mai mare accent pe învăţarea unor limbaje de programare şi pe programarea propriu-zisă, acordându-se o pondere mai mică analizei şi proiectării programelor. Specializarea în informatică nu înseamnă doar cunoaşterea limbajelor de programare,

ci în primul rând însuşirea metodelor moderne de analiză şi proiectare a aplicaţiilor

software.

Scopul acestei cărţi este de a contribui la învăţarea programării ca o disciplină unitară având o fundaţie ştiinţifică solidă, necesară programatorilor. Pentru aceasta este nevoie să încercăm să definim mai clar noţiunea de programare.

Conform cu [Sed, 1990], programarea poate fi privită ca o activitate generală de a extinde sau a de a modifica funcţionalităţile unui sistem. Este o activitate generală deoarece ea poate fi efectuată atît de specialişti (programatori) cât şi de nespecialişti (setarea unui telefon celular sau a unei alarme de acces într-o încăpere). Din acest

3

4

punct de vedere, activitatea de programare constă din două elemente fundamentale:

o componentă tehnologică şi o componentă ştiinţifică. Partea ştiinţifică include ele-

mente printre care se regăsesc structurile de date şi algoritmii necesari descrierii operaţiilor de manipulare a acestor structuri de date. Această abordare ne permite o independenţa a acestor structuri de date faţă de limbajele de programare şi faţă de

tehnologiile de proiectare utilizate în activitatea de programare. Programele sunt făcute pentru a rezolva probleme din viaţa de zi cu zi. Informaţia

prelucrată de un program este stocată cu ajutorul structurilor de date. Aceste structuri de date grupează într-o formă eficientă datele. O structură de date corect definită poate simplifica operaţia care prelucrează acele date sau o poate complica. De aceea structurile de date au o importanţă majoră în activitatea de proiectare

şi programare. Programele prelucrează informaţii. Informaţiile sunt organizate sub

formă de structuri de calcul. Modul în care reprezentăm structurile de date afectează claritatea, conciziunea, viteza de rulare şi capacitatea de stocare a programului. Dez- voltarea unui program complex este dificilă dacă programatorul nu posedă cunoştinţe în domeniul structurilor de date, algoritmicii şi a tehnicilor de programare. Dacă nu se cunoaşte o soluţie pentru rezolvarea unei probleme nu există o soluţie magică de a scrie un program care să rezolve acea problema. Un proverb afirmă că dacă nu ştii cum să ajungi într-un anumit loc atunci nu are importanţă cum ajungi în acel loc. Mai mult chiar, Murphi afirmă că orice problemă complexă are o soluţie simplă eronată. De aceea, înainte de a implementa un program într-un anumit limbaj de programare, este necesară înţelegerea problemei, descrierea pas cu pas a soluţiei, cu alte cuvinte este necesar a descrie problema prin intermediul unui algoritm. Din păcate nu există un algoritm care să aleagă algoritmul care rezolvă orice problemă. Ceea ce există sunt o serie de tehnici de dezvoltare a algoritmilor, numite în general tehnici de programare. Scopul principal al lucrării de faţă este familiarizarea celor care doresc să o înveţe, cu activitatea de programare. Vom vedea în ce constă această activitate şi vom remarca accentul pus pe gândirea omului, pe proiectarea algoritmilor şi corectitudinea lor, calculatorul fiind doar unealta care execută ceea ce "dictează" programatorul. Pentru a putea dicta calculatorului avem nevoie de un limbaj înţeles de ambele părţi; limbajul ales în acest scop este Pascal. De asemenea, vom prezenta metodele de programare cunoscute în prezent şi discutate în literatura de specialitate. Vom învăţa să analizăm algoritmii, dar vom fi mai puţin preocupaţi de măsurarea complexităţii unui program, accentul fiind pus pe modul în care el poate fi obţinut. Noţiunile şi conceptele prezentate sunt însoţite de exemple simple, în care s-au folosit: limbajul Pseudocod în descrierea algoritmilor, un limbaj de specificare informal în descrierea tipurilor abstracte de date şi limbajul Pascal pentru codificare.

Cuprins

1 Bazele algoritmilor

 

11

1.1 Descrierea algoritmilor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

11

1.1.1 Algoritm, program, programare

 

11

1.1.2 Scheme logice .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

11

1.1.3 Limbajul PSEUDOCOD .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

12

1.1.3.1 Algoritmi liniari

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

15

1.1.3.2 Algoritmi cu ramificaţii

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

17

1.1.3.3 Algoritmi ciclici

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

19

1.1.4 Calculul efectuat de un algoritm

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

22

1.1.5 Rafinare în paşi succesivi

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

24

1.1.6 Probleme propuse

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

26

1.1.7 Subalgoritmi

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

26

1.1.7.1 Conceptul de subalgoritm

 

26

1.1.7.2 Apelul unui subalgoritm

 

.

.

.

29

1.2 Elaborarea algoritmilor. Propoziţii nestandard

.

.

.

.

.

.

.

.

.

.

.

.

.

31

1.3 Proiectarea ascendentă şi proiectarea descendentă

 

34

1.4 Proiectarea modulară

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

41

1.5 Apel recursiv

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

46

1.6 Programarea structurată

 

.

.

.

.

.

.

.

.

.

.

47

1.7 Probleme propuse .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

47

2 Complexitatea algoritmilor

 

51

2.1 Etapele rezolvării unei probleme

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

51

2.2 Noţiunea de algoritm şi cea de program

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

51

2.3 Modelul abstract al Maşinii Turing. Teza Turing-Church

 

52

2.4 Analiza, proiectarea şi implementarea algoritmilor şi complexitatea al-

goritmilor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

53

 

5

6

CUPRINS

2.5 Operaţia de bază, cheia studiului complexităţii

 

.

.

.

.

.

.

.

.

.

.

.

.

.

53

2.6 Clase de algoritmi

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

54

2.7 Eficienţa algoritmilor .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

54

2.8 Funcţiile de complexitate

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

54

2.9 Apartenenţa la o clasă de complexitate

 

55

2.10 Limita inferioară sau efortul minimal. Algoritm optimal

 

58

2.11 Complexitatea algoritmilor şi dificultatea problemelor

.

.

.

.

.

.

.

.

.

59

2.12 Complexitatea de timp .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

59

2.13 Probleme rezonabile şi probleme nerezonabile. Clasa problemelor P -

 

polinomiale

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

60

2.14 Probleme de decizie şi probleme de optimizare

 

60

2.15 Clasa problemelor NP (non - deterministic polinomiale)

 

.

.

.

.

.

.

.

.

61

2.16 Reducţia polinomială a problemelor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

61

2.17 Teorema lui Cook. Probleme NP-Complete

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

62

2.18 Clasa problemelor NP-Complete

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

62

2.19 Marea Întrebare a Complexităţii algoritmilor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

63

2.20 Algoritmi aproximativi .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

64

2.21 Probleme insolvabile algoritmic

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

65

2.22 Complexitatea algoritmilor, calculatorul şi viitorul

.

.

.

.

.

.

.

.

.

.

.

66

3

Pogramare în limbajul PASCAL

 

67

3.1 Mediul de programare Turbo Pascal

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

67

3.2 Programe simple Pascal

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

71

3.3 Structura unui program Pascal

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

73

3.4 Constante şi variabile Pascal

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

74

3.5 Tipuri de date

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

75

 

3.5.1 Tipul întreg .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

77

3.5.2 Tipul real

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

77

3.5.3 Tipul boolean

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

78

3.5.4 Tipul caracter

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

78

3.5.5 Tipul enumerare

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

78

3.5.6 Tipul subdomeniu

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

79

3.6 Expresii Pascal

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

79

 

3.6.1 Funcţii predefinite

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

79

3.6.2 Expresii aritmetice

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

81

3.6.3 Expresii relaţionale .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

82

3.6.4 Expresii logice

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

82

3.7 Declaraţii Pascal

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

83

CUPRINS

7

3.8 Definirea constantelor

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

84

3.9 Definirea tipurilor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

84

3.10 Declararea variabilelor

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

85

3.11 Instrucţiuni Pascal

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

86

 

3.11.1 Instrucţiunea de atribuire

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

86

3.11.2 Instrucţiunea compusă şi instrucţiunea vidă

 

87

3.11.3 Citirea şi scrierea datelor

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

87

3.11.4 Instrucţiuni condiţionale .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

89

3.11.5 Instrucţiuni repetitive

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

91

3.12 Subprograme Pascal

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

97

3.13 Funcţii Pascal .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

99

3.14 Instrucţiunea apel de procedură .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

99

3.15 Apel recursiv

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

105

3.16 Tipuri de date structurate .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

106

3.17 Tipul referinţă

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

116

3.18 Probleme propuse

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

118

4

Structuri de date

 

121

4.1 Lista liniară simplu înlănţuită

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

121

 

4.1.1 Definiţii

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

121

4.1.2 Operaţii specifice listei .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

123

4.1.3 Probleme propuse

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

128

4.2 Lista dublu înlănţuită

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

130

 

4.2.1 Definiţii

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

130

4.2.2 Operaţii specifice listei .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

131

4.2.3 Probleme propuse

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

138

4.3 Stiva (stack) .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

139

 

4.3.1 Generalităţi .

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

139

4.3.2 Stiva – alocare statică

.

.