Documente Academic
Documente Profesional
Documente Cultură
Algoritmică
şi
programare
Cluj-Napoca
2016
Cuprins
1. Descrierea algoritmilor, limbajul Pseudocod................................................ 2
1.1. Descrierea algoritmilor. ........................................................................................ 2
1.2. Limbajul Pseudocod. ............................................................................................ 4
2. Proceduri, funcţii. ............................................................................................. 8
2.1. Subalgoritmi. ......................................................................................................... 8
2.2. Funcţii. ................................................................................................................... 9
1
1. Descrierea algoritmilor, limbajul Pseudocod.
Blocurile delimitatoare (Start şi Stop) (figura 1.a şi 1.b) vor marca începutul respectiv
sfârşitul unui algoritm dat printr-o schemă logică. Descrierea unui algoritm prin schemă logică va
începe cu un singur bloc Start şi se va termina cu cel puţin un bloc Stop.
Blocurile de intrare/ieşire (Citeşte şi Afişează) (figura 1.c şi 1.d) indică introducerea unor
Date de intrare respectiv extragerea unor Rezultate finale. Ele permit precizarea datelor iniţiale
cunoscute în problemă şi tipărirea rezultatelor cerute de problemă.
Blocul Citeşte iniţializează variabilele din lista de intrare cu valori corespunzătoare, iar blocul
Afişează va preciza rezultatele obţinute (la execuţia pe calculator cere afişarea pe ecran a valorilor
expresiilor din lista de ieşire).
Start
Citeşte listă_var_intrare Afişează listă_expr.ieşire
Stop
a) c) d)
b)
Da Nu <0 >0
Var Condiţie Epr. aritm.
=0
e) f) g)
i
i
h)
Figura 1. Blocurile schemelor logice.
Algoritmul de rezolvare a Da
problemei va citi mai întâi datele a=0 Mesaj „a=0”
problemei, marcate prin variabilele a, Nu
b şi c. Va calcula apoi discriminantul 1
şi va continua în funcţie de b2-4ac
valoarea lui , aşa cum se poate
Da Nu -b+
vedea în figura 2. Re-b / 2a <0 x1
2a
Im-/2a -b-
x2
2a
Stop
3
1.2. Limbajul Pseudocod.
Limbajul Pseudocod a fost conceput pentru descrierea algoritmilor. Limbajul Pseudocod are două
tipuri de propoziţii:
- standard (care au o structură fixă şi este formată cu ajutorul unor cuvinte cheie);
- propoziţii nestandard (care descriu părţi ale algoritmului încă incomplet elaborate,
nefinisate, asupra cărora urmează să se revină) şi
- comentarii (texte scrise între acolade sau alte semne distinctive utilizate pentru
documentarea algoritmului).
Propoziţiile limbajului Pseudocod se vor executa în ordinea întâlnirii lor în text, asemenea oricărui
text al limbii române.
În descrierea algoritmilor se recomandă o scriere structurată prin utilizarea următoarelor
structuri:
-secvenţială (formată dintr-o succesiune de propoziţii simple);
-alternativă (permite executarea anumitor ramuri în funcţie de anumite condiţii);
-repetitivă (prin care putem executa aceleaşi propoziţii de mai multe ori).
Sf_Dacă; Sf_Dacă;
interpretată astfel: dacă este îndeplinită această Condiţie atunci se execută secvenţa de propoziţii
care urmează până la sfârşitul structurii, iar în caz contrar se trece direct la urmatoarea structură;
aceasta se interpretează astfel: dacă această Condiţie este îndeplinită se execută prima secvenţă, dacă
nu, a doua.
care se poate “traduce” astfel : se caută valoarea expresiei în listele de valori şi se execută secvenţa
corespunzătoare. Dacă valoarea calculată nu se regăseste în nici o listă (şi apare alternativa Altfel
care este opţională, atunci se execută ultima secvenţă notată cu n+1).
Structurile repetitive permit executarea unei secvenţe de propoziţii de mai multe ori (de un
anumit număr de ori, sau câtă vreme este îndeplinită o anumită condiţie, sau până când este
îndeplinită o anumită condiţie). Pentru descrierea structurilor repetitive există trei variante pe care le
putem alege în funcţie de problema concretă pe care dorim să o rezolvăm.
Structura Pentru este o structură repetitivă cu un număr bine determinat de paşi, în schimb
structura Cât_Timp (cu test iniţial) şi structura Repetă (cu test final) sunt structuri repetitive cu un
număr necunoscut de paşi (lucru pe care îl vom vedea imediat).
- structura repetitivă Pentru se descrie prin propoziţia :
Pentru Varc := Li , Lf [ , Pas ] Execută
Secvenţă
Sf_Pentru;
având următoarea semnificaţie : se execută secvenţa (corpul structurii) dând succesiv valori
variabilei contor (Varc ) începând de la limita iniţială (Li) până la limita finală (Lf) cu pasul precizat
(implicit este 1, adică dacă lipseşte Pas, atunci se consideră egal cu 1).
5
- structura repetitivă Cât_Timp are format general :
Cât_Timp Condiţie Execută
Secvenţă
Sf_Cât_Timp;
şi se interpretează astfel : dacă această condiţie este îndeplinită atunci se execută secvenţa şi din nou
se verifică condiţia, şi asa mai departe. În momentul în care condiţia nu este îndeplinită se termină
structura repetitivă şi se continuă cu urmatoarea structură.
Repetă
Secvenţă
Până_Când Condiţie ;
având semnificaţia : se execută secvenţa descrisă apoi se verifică dacă este îndeplinită condiţia
precizată. Dacă aceasta este îndeplinită se termină structura repetitivă, iar dacă nu este îndeplinită,
atunci de execută din nou secvenţa şi se reevaluează condiţia.
Secvenţă
Da Nu
Condiţie Secvenţă Condiţie
Nu Da
Structura Cât_Timp Structura Repetă
Figura 3.
6
Algoritmul următor, dat ca exemplu, determină primele n (n dat) numere prime.
Ca exemplu de folosire a structurii Repetă vom scrie următorul algoritm care determină cel
mai mare numar n de patru cifre pentru care este îndeplinită condiţia :
7
2. Proceduri, funcţii.
Este foarte bine ca atunci când rezolvăm o problemă (mai ales dacă aceasta este mai
complexă) să o împărţim în subprobleme pe care apoi să le rezolvăm pe rând, eventual dacă aceste
subprobleme nu sunt simple, pot la rândul lor să fie împarţite, pâna când aceste subprobleme sunt
elementare (simple). Aceasta înseamnă că o problemă complexă P se poate descompune în mai
multe subprobleme mai simple Si . Algoritmul de rezolvare al unei subprobleme Si devine în acest
caz un subalgoritm pentru algoritmul de rezolvare al problemei P.
De asemenea este posibil ca o subproblemă, la rândul său, să fie descompusă în mai multe
subprobleme mai simple, şi aşa mai departe. Aceasta înseamnă că un subalgoritm poate să apleleze la
rândul său unul sau mai mulţi subalgoritmi. Acest lucru chiar este recomandat pentru a amâna
detaliile nesemnificative. Aceste detalii se vor descrie în subalgoritmii apelaţi.
Uneori o subproblemă se poate rezolva mai simplu aplelând o funcţie, care desigur va trebui
să fie definită. Modul de utilizare şi de descriere a funcţiilor va fi prezentată în paragraful 2.2.
2.1. Proceduri.
Lista parametrilor actuali conţine toate datele de intrare (cele cunoscute în subproblema
corespunzătoare care pot fi anumite expresii) şi toate rezultatele (datele de ieşire, deci variabile)
obţinute în subalgoritm.
Parametrii formali marchează datele de intrare (cele presupuse cunoscute) şi datele de ieşire
(rezultatele obţinute de subalgoritm).
Între lista parametrilor formali din definiţia subalgoritmului şi lista parametrilor actuali din
propoziţia de apel trebuie să existe o corespondenţă biunivoca (ca număr, tip, ordine, etc).
8
Dacă de exemplu pentru trei mulţimi date A, B şi C dorim să calculăm AB, AC şi BC,
atunci vom apela un subalgoritm care construieşte reuniunea a două mulţimi de trei ori.
Acest subprogram va calcula reuniunea R :=XY, X , Y R:=X R
pentru orice mulţimi X, Y date.
Subprogramul va avea doi parametri (formali) de intrare X şiYY şi un parametru de ieşire
R. El va fi apelat pentru a calcula succesiv reuniunile AB, AC şi BC.
2.2. Funcţii.
Destul de frecvent în cadrul unor algoritmi este necesar calculul valorilor unei funcţii în
diferite puncte. În această situaţie este de preferat sa definim funcţia printr-un subalgoritm de tip
funcţie după care putem să o referim pentru calculele în care aceasta intervine.
Definirea unui subalgoritm de tip funcţie se aseamănă cu descrierea anterioară (pentru
subalgoritmi de tip procedură) având un antet (care precizează numele funcţiei şi argumentele
acesteia), un corp (prin care este descris subalgoritmul) şi o marcă de sfârşit de funcţie :
În corpul funcţiei trebuie să existe cel puţin o atribuire prin care funcţia primeşte o
valoare.
Apelul unei funcţii se face scriind într-o expresie numele funcţiei urmat de lista parametrilor
actuali. Trebuie să existe o corespondenţa biunivoca între parametrii actuali si cei formali folosiţi în
definiţia funcţiei. Deşi denumirile variabilelor din cele două liste pot să difere, rolul variabilelor care
se corespund este acelaşi. Mai exact, parametrul formal si parametrul actual corespunzător trebuie să
se refere la aceeaşi entitate, trebuie să aiba aceeaşi semnificaţie, să reprezinte aceeaşi structură de
date.
9
Este permis ca un subprogram de tip funcţie să aibă chiar şi parametrii de ieşire, deci din
acest punct de vedere putem considera că o funcţie este mai “generoasă” pentru că va returna o
valoare în plus prin valoarea funcţiei.
De exemplu funcţia Există (b,A,n,p) de tip boolean ne va returna valoarea True dacă b se
află în şirul A (cu n componente) şi False în caz contrar. Însă este posibil ca în primul caz (în care
există un element ap pentru care b=ap) să obţinem şi indicele (prima poziţie) pe care se află acel
element. Atunci funcţia se poate apela astfel :
. . .
Dacă Există (b,A,n, p) Atunci Tipareşte p, ap
Altfel Tipareşte ‘ Nu există.’
Sf_Dacă;
. . .
Funcţia Există descrisă în continuare se poate uşor simplifica pentru a obţine o funcţie Apart
(b,A) utilă în exemplul anterior (yX).
Există numeroase probleme în care soluţia (rezolvarea) recursivă este mult mai simplă. Este
posibil ca un subalgoritm să se apeleze pe el însuşi. Într-un astfel de caz spunem că apelul este
recursiv, iar subalgoritmul respectiv este definit recursiv. Un exemplu bine cunoscut este funcţia
factorial definită astfel:
n! = n * (n1)! .
10
Este însă foarte important ca acestă funcţie (formulă) să fie completă, adică să capete
consistenţă. Aceasta înseamnă că trebuie definită o astfel de funcţie şi direct (nerecursiv), pentru
anumite valori. În acest exemplu va trebui să dăm consistenţa formulei pentru n=1 sau n=0 , adică
să precizăm că 0!=1 sau 1! =1.
În final putem să spunem că funcţia factorial poate fi definită astfel :
n! = 1 dacă n<2
11
De aici rezultă că funcţia care determină maximul dintr-un şir X cu n componente poate fi
scrisă astfel :
Funcţia Apart (b,A,k) prin care putem decide dacă b aparţine primelor k elemente din şirul A,
poate fi scrisă recursiv astfel :
Funcţia Apart (b,A,k) Este :
Apart := (k>0) şi ( Apart(b,A,k-1) Sau (b=ak) )
Sf_Apart.
( b aparţine primelor k dacă şirul are cel puţin un element (k>0) şi b aparţine sau subşirului primelor
k-1 elemente sau este egal cu elementul ak. Prin apelul Apart(b,A,Card(A)) putem decide dacă bA
sau bA.
12
Bibliografie
13