Documente Academic
Documente Profesional
Documente Cultură
DESCRIEREA ALGORITMILOR
Algoritmi
Orice activitate umană se desfăşoară, în general, pa baza unor principii
logice sau, altfel spus, a unui algoritm bine definit. Deşi nu se conştientizează acest
lucru, omul acţionează conform unor algoritmi, care reprezintă expresia regulilor
impuse de parcurgerea logică a etapelor necesare pentru a ajunge de la o situaţie
iniţială la un anumit rezultat.
Funcţionarea calculatoarelor se aseamănă în mare măsură cu activitatea
umană. În cazul acestora, este obligatorie conştientizarea faptului că întreaga
activitate a echipamentului de calcul se bazează pe respectarea unor algoritmi,
algoritmi ce sunt elaboraţi de factorul uman dotat cu raţiune şi capacitate de
analiză. Calculatorul nu dispune de calităţile omului, ca atare, în procesul de
rezolvare a unei probleme cu ajutorul echipamentului electronic de calcul este
obligatorie parcurgerea unei etape importante, şi anume elaborarea algoritmului de
calcul. Succesul rezolvării problemei depinde de calitatea algoritmului întocmit de
către utilizator şi aplicat de echipamentul de calcul prin intermediul unui program.
Calculatoarele numerice prelucrează informaţiile prin executarea unor
operaţii simple. Deşi operaţiile sunt elementare, prin înlănţuirea unei mulţimi de
operaţii se poate ajunge la prelucrări deosebit de complexe. Combinarea operaţiilor
nu se face la întâmplare, ea supunându-se unor reguli bine precizate. Studiul
acestor reguli are la bază noţiunea de algoritm. Noţiunea de algoritm este strâns
legată de noţiunea de calcul.
Intuitiv un algoritm de calcul este o mulţime finită de operaţiuni cunoscute
care executate într-o ordine bine stabilită, pornind de la un set de valori, numite
date de intrare, conduc într-un timp finit la un set de valori, numite date de ieşire.
Algoritmul reprezintă o mulţime de asemenea calcule. Altfel spus, prin
algoritm se înţelege metoda de rezolvare a unei probleme într-un număr finit de
paşi. Metoda de rezolvare este în esenţă un şir de operaţii precise, care dacă sunt
îndeplinite conduc la rezultatul dorit într-un număr finit de paşi.
Se poate spune că un algoritm constituie un sistem de reguli care, aplicat la
o clasă de probleme de acelaşi tip, conduce de la o situaţie iniţială la un rezultat
final prin intermediul unor operaţii succesiv ordonate, unic determinate.
O informaţie iniţială pentru care un algoritm de calcul este aplicabil, se
numeşte informaţie admisibilă. Totalitatea informaţiilor de acest gen constituie
domeniul algoritmului.
Cunoscând faptul că orice algoritm conţine un anumit număr de etape
numite şi paşii algoritmului, se poate afirma că regulile algoritmului f aplicate
asupra informaţiei iniţiale, care aparţine domeniului D, determină întotdeauna
obţinerea informaţiei finale corespunzătoare. Ca urmare, un algoritm poate fi
definit ca o funcţie:
1
f = D F unde: D= domeniul algoritmului (informaţiile iniţiale);
F= soluţia finală (informaţiile finale).
În general, un algoritm se caracterizează prin:
unicitatea. regulile algoritmului determinând unicitatea ordinii în care au
loc toate transformările intermediare, dar şi obţinerea informaţiei finale,
după care activitatea algoritmului se opreşte.
finalitate. Orice pas al algoritmului trebuie să se termine după un număr
finit de paşi, şi anume atunci când este obţinut rezultatul final, nu cel
intermediar. Această proprietate se mai numeşte şi realizabilitate
potenţială.
claritate (să fie definit). Fiecare pas al algoritmului trebuie să fie precis
definit. Operaţiile ce trebuie efectuate în cadrul fiecărui pas trebuie să
fie specificate în mod riguros, precis, astfel încât să nu apară ambiguităţi
în interpretare lui de către cel care îl execută. Totodată, trebuie riguros
precizate toate etapele de calcul ce trebuie urmate pentru a obţine soluţia
finală;
eficacitate. Orice algoritm trebuie să fie eficace. Aceasta înseamnă că
toate operaţiile algoritmului să poată fi efectuate de un individ cu creion
şi hârtie într-un interval de timp finit.
generalitate (universal) - adică să permită rezolvarea oricărei probleme
dintr-o anumită clasă de probleme pentru care a fost stabilit.
Ca exemple de algoritmi cunoscuţi din matematică amintim: algoritmul lui
Newton pentru aflarea rădăcinii pătrate aritmetice a unui număr, algoritmul lui
Euclid pentru aflarea celui mai mare divizor comun a două numere etc .
Descrierea algoritmilor.
Transcrierea algoritmului într-un limbaj de programare, în vederea rezolvării
lui cu ajutorul calculatorului numeric poartă numele de program. Programele
transmise calculatorului, ca o reprezentare fidelă a algoritmului de calcul sunt
transcrise într-un limbaj “înţeles” de calculator, nu conţine ambiguităţi şi specifică
precis şi clar doar operaţiile pe care calculatorul le poate executa.
Scrierea unui algoritm poate fi făcută rareori direct într-un limbaj de
programare. Ca atare realizarea unui program comportă, uzual nişte etape
intermediare.
În vederea întocmirii unui algoritm de calcul şi utilizării acestuia la
calculator, este necesară realizarea următoarelor activităţi:
definirea problemei;
formularea modelului matematic al problemei;
stabilirea algoritmului de rezolvare a problemei;
reprezentarea algoritmului;
scrierea programului corespunzător algoritmului, prin utilizarea unui
limbaj de programare adecvat;
transpunerea programului pe un suport tehnic de memorie;
2
testarea, depanarea şi execuţia programului;
întreţinerea programului.
Calitatea programelor şi succesul execuţiei acestora depinde de calitatea
algoritmilor utilizaţi, de respectarea caracteristicilor specifice pentru orice
algoritm, cât şi de mărimile şi operaţiile utilizate în descrierea algoritmilor.
Mărimile utilizate în cadrul algoritmilor pot fi clasificate astfel:
după tipul datelor, respectiv din ce mulţime poate lua valori mărimea
respectivă:
date numerice;
date alfanumerice;
date logice;
date calendaristice.
după natura datelor:
date constante;
date variabile.
Operaţiile utilizate în descrierea algoritmilor sunt:
operaţii de calcul aplicate asupra variabilelor. În cadrul acestora, se
utilizează operatorii aritmetici +, -, , /,* ce corespund operaţiilor de
adunare, scădere, înmulţire, împărţire şi ridicare la putere, care se împart
pe trei nivele de prioritate:
ridicarea la putere - prioritatea maximă;
înmulţirea şi împărţirea;
adunarea şi scăderea.
operaţii de atribuire (x=(a+b)-c);
operaţii de decizie (relaţionali , , , , sau logici , , )
Descrierea algoritmilor se realizează cu ajutorul reprezentărilor grafice sau
textuale cât mai sugestive, care să permită obţinerea unei imagini de ansamblu
asupra etapelor din cadrul acestora, dar şi transpunerea mai facilă a algoritmilor în
programe.
Orice reprezentare trebuie să reflecte toate etapele, toate operaţiile conţinute
de algoritmi, ceea ce presupune existenţa unor convenţii de reprezentare a acestora.
Algoritmii pot fi reprezentaţi grafic cu ajutorul schemelor logice şi a diagramelor
arborescente, iar reprezentarea textuală se efectuează cu ajutorul limbajelor de tip
pseudocod.
Scheme logice
Schemele logice reprezintă scrierea algoritmilor de calcul cu ajutorul unor
simboluri (forme) geometrice, care evidenţiază diferite tipuri de acţiuni.
Realizarea schemei logice corespunzătoare unui algoritm este utilă fie la
depanarea programelor, fie la lucrul în echipă, fie la schimbul de informaţii dintre
diverse grupuri de programatori,întrucât ea specifică precis şi clar ordinea de
parcurgere a blocurilor (simbolurilor geometrice).
3
Simbolurile uzuale utilizate în realizarea schemelor sunt cuprinse în tabelul
de mai jos:
START
CITEST
E
i
SUBRUTINA
XEITES
TE
PRINT
i
STOP
4
- structura alternativă (de selecţie) necesită punerea în evidenţă a tuturor
căilor de rezolvare a problemei – cu descrierea operaţiilor specifice de
realizare pe fiecare variantă – ce apar ca urmare a existenţei unei condiţii
date în cadrul algoritmului. Pot fi utilizate trei tipuri de structuri
alternative:
Structura alternativă cu selecţie simplă (IF – THEN) – apariţia condiţiei
C presupune existenţa a două căi alternative de parcurgere în continuare a
operaţiilor;
Structura alternativă cu selecţie dublă (IF – THEN - ELSE) – dacă este
îndeplinită condiţia C, se execută operaţiile de pe ramificaţia notată cu
DA, altfel se execută alte operaţii, total diferite, evidenţiate pe ramura
notată cu NU;
Structura alternativă cu selecţie multiplă (CASE – OF) – permite selecţia
între mai mult de două posibilităţi de continuare în rezolvarea problemei.
START START
I
I
CITEST CITEST
I
E DA E DA I
A2
i i
I
EITES EITES
TE A1 A3
TE
PRINT PRINT
i
i
STOP STOP i
=Vi
A
A
C
NU V=V+r
C 5
DA
A V>V
r
WHILE - DO DO - UNTIL DO - FOR
Exemplu:
Se cere algoritmul şi schema logică pentru calculul lui n!
Paşii algoritmului de calcul sunt :
1. citeşte valoarea lui n;
2. atribuie lui P valoarea 1;
3. atribuie lui I valoarea 1;
4. atribuie lui P valoarea expresiei P * I;
5. atribuie lui I valoarea expresiei I + 1;
6. dacă I<N atunci treci la pasul 4;
7. scrie valoare lui P;
8. stop.
Schema logică corespunzătoare algoritmului:
START
Citeşte
n
p: = 1
i: = 1
p: = p * i
i: = i + 1
Diagrama arborescentă
Diagrama arborescentă constituie o altă modalitate de reprezentare grafică a
algoritmilor. Ca şi în cazul schemelor logice, există mai multe convenţii de
reprezentare a operaţiilor în cadrul algoritmilor.
Limbajul Pseudocod
Spre deosebire de schemele logice, limbajele Pseudocod folosesc cuvinte cu
înţeles prestabilit (numite cuvinte cheie) şi câteva reguli simple de aliniere a
textului scris.
Pseudocodul reprezintă un mijloc de exprimare naturală şi dezvoltare
sistematică a algoritmilor.
6
Pseudocodul are puţine reguli sintactice lăsând programatorului o mare
libertarte în exprimarea acţiunilor algoritmilor.
Pseudocodul permite specificarea algoritmilor prin două tipuri de enunţuri
nestandard şi standard.
Enunţurile nestandard sunt fraze în limbaj natural care pot fi utilizate de
programator în schiţarea formelor iniţiale ale algoritmilor şi sunt precedate de
***. În dezvoltarea algoritmilor, enunţurile nestandard sunt înlocuite treptat cu
enunţuri standard care exprimă operaţii cu corespondente directe în limbajele de
programare.
În forma standard fiecare comandă (operaţie) este reprezentată în limbajul
Pseudocod printr-un cuvânt care exprimă operaţia ce trebuie executată, însoţit de
obicei, de elemente suplimentare care îi particularizează efectul.
Limbajul pseudocod nu este un limbaj de programare, ci o modalitate
textuală de reprezentare a algoritmilor. El poate fi utilizat în locul reprezentărilor
grafice, dar faţă de schemele logice este mult mai puţin utilizat de către
programatori.
Construcţia de bază a limbajului pseudocod este propoziţia, un algoritm
fiind reprezentat printr-o succesiune de propoziţii care pot fi:
- propoziţii simple care exprimă operaţii ce pot fi transpuse direct într-un
limbaj de programare;
- propoziţii complexe, notate cu simbolul #, care urmează să fie detaliate
ulterior până la nivelul propoziţiilor simple.
Fiecare propoziţie începe cu un verb care exprimă operaţia descrisă. Un
exemplu de algoritm reprezentat cu ajutorul limbajului pseudocod poate fi
următorul:
citeşte var
atribuie var=expr
execută nume_proced
scrie var
stop
unde: var semnifică o variabilă;
expr reprezintă o expresie algebrică sau logică;
nume_proced este numele unei proceduri, care va fi detaliată
ulterior.
Pentru a fi puse în evidenţă operaţiile, verbele sunt subliniate.
Cuvântul care identifică operaţia se numeşte cuvânt cheie. Enunţurile
standard utilizate în limbajele Pseudocod şi semnificaţia lor sunt următoarele:
a) operaţia de intrare (citire) - constă în transferul unor valori de pe
mediul de intrare (eventual de pe cartele sau de la un terminal) în locaţii de
memorie specificate prin ‘lista de variabile’
Structura comenzii: citeşte lista de variabile
Exemplu: citeşte a,b,c
7
În locaţiile desemnate prin variabilele a,b,c se transferă valori de pe mediul de
intrare.
b) Operaţia de ieşire (scriere) - constă în transferul unor valori din
locaţiile de memori specificate prin ‘lista de variabile’, pe mediul de ieşire
(imprimantă, display etc.)
Structura comenzii: scrie lista de variabile
Exemplu: scrie x,a,d,g
Conţinutul locaţiilor de memorie desemnate prin variabilele x,a,d,g este
transferat de mediul de ieşire.
c) Operaţia de atribuire – constă în calculul valorii unei expresii, valoare ce
se atribuie unei variabile.
Structura comenzii: atribuie variabilă expresie
Exemplu: atribuie D a*b+c
atribuie E x /\ y \/ z
Variabilelor D,E li se atribuie valorile obţinute în urma calculului valorii
expresiilor din dreapta semnului
d) Operaţia de oprire – are ca efect oprirea execuţiei comenzilor în
calculator
Structura comenzii: stop
e) Secvenţa – este o structură realizată prin scrierea succesivă (în secvenţă) a
comenzilor componente.
Exemplu: citeşte A,B
atribuie C A + B
scrie A , B , C
stop
Efectul execuţiei unei comenzi depinde de poziţia comenzii în cadrul secvenţei .
f) Decizia – este o structură care asigură alegerea pentru execuţie a unei
secvenţe din două alternative posibile.
Structura comenzii: dacă condiţie atunci
secvenţa1
altfel
secvenţa 2
[]
Începutul comenzii de decizie este marcat de cuvântul cheie “dacă” iar
sfârşitul său de semnul []
Execuţia acestei comenzi comportă următoarele etape:
se evaluează “ condiţia”;
dacă rezultatul evaluării este adevărat (condiţie îndeplinită) se execută
secvenţa 1;
în caz contrar se execută secvenţa 2.
După executarea secvenţei 1 sau a secvenţei 2 se trece la următoarea
comandă (cea după semnul [] )
8
Observaţie: În cazul în care secvenţa care urmează după cuvântul cheie “altfel”
lipseşte, se utilizează forma simplificată a deciziei:
dacă condiţie atunci
secvenţa1
[]
În cazul în care condiţia nu este îndeplinită se trece direct la comanda ce
urmează deciziei
Exemplul:
dacă A > B atunci
scrie A
altfel
scrie B
[]
Efectul execuţiei exemplului de mai sus este următorul:dacă valoarea
variabilei A este mai mare decât a variabilei B se scrie valoarea lui A în caz contrar
se scrie valoarea variabilei B şi nu valoarea variabilei A.
Exemplul: Decsrierea în Pseudocod a algoritmului de aflare a celui mai
mare element din 3 valori reale desemnate prin variabilele a,b,c.Variabila “x” va
conţine cel mai mare element din cele 3 valori.Algoritmul de rezolvare a unei
probleme nu este unic.Ca atare se dau două descrieri Pseudocod pentru rezolvarea
acestei probleme.
a) varianta 1
citeşte a,b,c
dacă a>b atunci
atribuie x a
altfel
atribuie x b
[]
dacă c > x atunci
atribuie x c
[]
scrie x
stop
b) varianta 2
citeşte a,b,c
atribuie x a
dacă x < b atunci
atribuie x b
[]
dacă x < c atunci
atribuie x c
[]
9
scrie x
stop
O variantă simplificată : citeşte a,b,c,
atribuie x a
dacă x < b atunci atribuie x b
dacă x < c atunci atribuie x c
scrie x
stop
Observaţie: Ultima variantă a algoritmului are avantajul că poate fi uşor
generalizată pentru aflarea maximului unui şir.
g) Selecţia reprezintă o extindere a operaţiei de decizie, ea permitând alegerea
unei alternative din mai multe posibile.Forma generală a comenzii de selecţie
este următoarea :
alege expresia dintre
c1 : secvenţa 1
c2 : secvenţa 2
.
.
cn : secvenţa n
rest : secvenţa n+1
[]
Unde c1 , c2 , ... cn sunt etichete şi se folosesc pentru identificarea
secvenţelor.Sfârşitul comenzii este marcat de _[] iar liniile textului selecţiei sunt
marcate prin etichetele c.
Modul de execuţie al comenzii de selecţie este următorul:
se evaluează expresia
se identifică eticheta ci ce are aceeaşi valoare cu expresia ( în urma
evaluării expresiei)şi este selectată secvenţa corespunzătoare.Dacă nici o
etichetă nu are valoarea expresiei atunci este selectată secvenţa n+1,
corespunzătoare etichetei rest.
se execută secvenţa selecctată şi se sare la sfârşitul comenzii de selecţie
adică după semnul [].
Exemplu: Să se adune valoarea întreagă v la una din variabilele s0,s1,s2 ,s3,
după cum restul împărţirii valorii v la 4 este 0,1,2 sau 3 .Descrierea în Pseudocod
arată astfel:
citeşte v,s0,s1,s2,s3
alege v – int ( v/4)*4 dintre
0: atribuie s0 s0 + v
1: atribuie s1 s1 + v
2: atribuie s2 s2 + v
3: atribuie s3 s3 + v
[]
scrie s0,s1,s2,s3
stop
10
În acest caz , eticheta “rest” şisecvenţa respectivă lipseşte ,deoarece
domeniul de valori ale expresiei este mulţimea (0,1,2,3).
h) Ciclul cu test final – În rezolvarea unei probleme , nu de puţine ori apare
situaţia executării repetate a unei secvenţe de operaţii.O astfel de combinaţie ,
în care execuţia unui grup de operaţii se repetă se numeşte ciclu sau
iteraţie.Pentru reprezentarea ei se utilizează o comandă de ciclare care
specifică atâtoperaţiile care se repetă cât şi condiţia de repetare.
Forma generală a comenzii de ciclare cu test final este următoarea:
repetă
secvenţa
până condiţia
[]
Modul de execuţie al comenzii de ciclare este următorul:
1-se execută secvenţa
2-se evaluează condiţia şi dacă rezultatul este fals(condiţie neîndeplinită)se
continuă cu etapa 1 , altfel execuţia comenzii se termină şi se trece la comanda
următoare.
Exemplu: Se dă algoritmul lui Euclid pentru afişarea celui mai mare
divizor comun a două numere întregi m,n(m>=n>0).
1. citeşte valorile lui m şi n
2. atribuie lui c valoarea lui n ( în variabila c se reţine cel mai mare divizor
comun )
3. atribuie lui r restul împărţirii întregi a lui m la n
4. dacă r diferit de 0 atunci treci la 7
5. scrie valoarea lui c
6. stop
7. atribuie lui m valoarea lui n
8. atribuie lui n valoarea lui r
9. treci la pasul 2
Se observă că operaţiile care se realizează calculul restului şiactualizarea
valorilor c, m şi n se repetă.
Folosind Descrierea în Pseudocod a algoritmului şi ciclul cu test final vom
avea:
citeşte m,n
repetă
atribuie c n , r m-int(m/n)*n
atribuie mn , n r
până r=0
_[]
scrie c
stop
11
Condiţia de terminare a ciclului poate fi orice expresie logică.Secvenţa de
operaţii din ciclu alcătuieşte corpul ciclului .Ea poate conţine oriceoperaţii,
inclusiv iteraţii.
i) Ciclul cu test iniţial – În cazul ciclurilor sau iteraţiilor condiţia de ciclare
poate apare şi la începutul secvenţei de ciclare
Forma generală este :
cât timp condiţia execută
secvenţa
[]
Condiţia poate fi orice expresie logică , iar secvenţa poate conţine orice
comenzi , inclusiv comenzi de ciclare.
Modul de execuţie al ciclului cu test iniţial :
1-se evaluează condiţia;dacă rezultatul este fals(condiţie neîndeplinită) execuţia se
termină,iar dacă rezultatul este adevărat se continuă secvenţa(etapa 2)
2-se execută secvenţa,după care se continuă cu 1.
În cazul în care rezultatul evaluării condiţiei este fals încă de la
început,secvenţa nu se execută niciodată spre deosebire de ciclul cu test final,când
secvenţa se executa cel puţin o dată.
Scrierea algoritmului lui Euclid în Pseudocod folosindciclul cu test iniţial
ne conduce la:
citeşte m,n
atribuie c n , r m-int(m/n)*n
cât timp r <> 0 execută
atribuie m n , n r, c n
atribuie r m-int(m/n)*n
[]
scrie c
stop
j) Ciclul de contor, cu forma generală:
pentru contor = val iniţială, val.finală,pas execută
secvenţa
[]
unde prin contor se înţelege o variabilă cu valori întregi:”valoarea iniţială, finală
şi pas” pot fi expresii aritmetice cu valori întregi.
Execuţia ciclului cu contor se explicitează astfel:
1) variabilei contor i se atribuie valoarea iniţială;
2) se verifică condiţia contor > val. Finală; dacă rezultatul este fals se
continuă cu, astfel execuţia ciclului se termină;
3) se execută secvenţa
4) se modifică valoarea contorului cu pasul p şi se continuă cu pasul 2)
Exemplu: aflarea lui n!
Observaţii: 1. Dacă pasul de ciclare este 1, se poate omite
2. Algoritmul a fost completat şi pentru cazul în care n = 0
citeşte n
12
atribuie p = 1
dacă n>0 atunci
pentru i=1,n execută
atribuie p=p*i
[]
[]
scrie p
stop
k) Proceduri şi funcţii
În rezolvarea unor probleme apar frecvent situaţii când un număr decomenzi
se repetă schimbându-se numai variabilele ce compun aceste comenzi,structura
comenzilor rămânând aceeaşi.
Pentru a nu repeta acel număr de comenzi în mai multe locuri în cadrul
descrierii algoritmului de rezolvare a problemei se folosesc procedurile şi funcţiile.
Procedura – descrie în termeni generali un algoritm cu posibilitatea de a
aplica acel algoritm în diverse cazuri particulare concrete.
Pentru a se identifica,procedurii i se asociază un nume.La definirea
procedurii trebuie să se asocieze un se de parametri , variabile care specifică
mărimile ce se modifică la fiecare apelare a procedurii.
Structura unei proceduri, în Pseudocod este :
Procedure nume (parametrii) este:
secvenţa
sfârşit
unde:
- nume = numele procedurii
- parametrii = parametrii formali ai procedurii
Apelul unei procedurei specifică numeleprocedurii,precum şi parametrii
actuali prin care se transmit valorile cu care se efectuează comenzile din
procedură.
Structura apelului unei proceduri este :
execută nume ( parametrii )
unde : - nume = numele procedurii ce se apelează
- parametrii = parametrii actuali ( efectivi ),adică cei pentru care
urmează a se efectua comenzile din procedură.
Exemplu: Să se construiască o procedură pentru aflarea normei unui
vector.Se ştie că norma unui vector A de n componente se defineşte prin relaţia:
S=
13
[]
sfârşit norma
Numele procedurii este “norma”.Parametrii de intrare necesari pentru a se
realiza calculele din procedură sunt vectorul a şi numărul de elemente ale
vectorului n, iar parametrul de ieşire este S,prin el se obţine rezultatul calculelor-
norma . Separarea parametrilor de ieşire de cel de intrare se face prin punct şi
virgulă . Parametrii de intrare şi cei de ieşire specificaţi la definirea procedurii se
numesc parametrii formali.
Exemplu: Să se folosească procedura definită pentru a determina dacă norma
vectorului x de l componente este mai mare decât norma vectorului w de m
componente.
Descrierea în Pseudocod a algoritmului de aflare a celei mai mari dintre
normele vectorilor x şi w este următoarea :
citeşte l ,(xi , i = 1, 1)
citeşte m,(xi , i = 1,m)
execută norma (x ,l ; s1)
execută norma (w,m; s2)
dacă s1>s2 atunci
scrie ‘norma vectorului x este mai mare’
altfel
scrie ‘norma vectorului w este mai mare’
[]
stop
În apelulprocedurii norma , parametrii x,l,s1,respectiv w,m,s2 sunt
parametrii actuali.
Comanda “execută” urmată de numele procedurii are ca efect execuţia
operaţiilor care constituie procedura cu numele specificat , în care valorile
parametrilor formali sunt înlocuite cu valorile parametrilor efectivi
corespunzători,adică parametrii a,n,s din procedura sunt înlocuiţi cu x,l,s1
respectiv w,m,s2 din apelul procedurii.
Corespondenţa dintre parametrii efectivi şi parametrii formali este
poziţională , adică parametrul care ocupă poziţia p în lista parametrilor formali
este înlocuit cu parametrul care ocupa poziţia p în lista parametrilor
efectivi.Aceasta substituţie se numeşte transferul parametrilor.Comanda “ execută”
se termină odată cu terminarea execuţiei ultimei operaţii din procedură.
Funcţia
Atunci când procedura calculează o singură valoare se poate utiliza un tip
particular de procedură numit funcţie.Descrierea unei funcţii cuprinde :
- linia de definire a funcţiei
- secvenţa de operaţii ce constituie corpul funcţiei
- linia finală
Structura unei funcţii în Pseudocod este următoarea :
funcţia nume (parametrii ) este:
secvenţa
14
sfârşit
unde:
- nume reprezintă numele funcţiei
- parametrii sunt parametrii funcţiei şi trebuie să fie doar parametrii de
intrare
Singurul parametru de ieşire în cazul funcţiei este considerat chiar numele
funcţiei care este utilizat în secvenţa de operaţii din corpul funcţiei ca orice
parametru. Valoarea acestui parametru reprezintă valoarea funcţiei.Secvenţa din
corpul funcţiei trebuie să conţină o comandă de atribuire prin care numelui funcţiei
i se atribuie o valoare.
Exemplu: Să se definească o procedură pentru calculul lui n!.
Descrierea în pseudoco a funcţiei este :
funcţia fact(m) este :
atribuie p 1
dacă m>1 atunci
pentru i=1,m,1execută
atribuie p p*i
[]
[]
atribuie fact p
sfârşit fact
Apelul unei funcţii este considerat ca operand în cadrul expresiilor .Structura
apelului unei funcţii în Pseudocod este :
nume( parametri )
unde :
- nume -reprezintă numele funcţiei
- parametrii - reprezintă lista parametrilor actuali de intrare ai funcţiei
Eexmplu:
Să se folosească funcţia descrisă mai sus pentru calculul combinărilor:
= =
Programarea
15
În general, scopul final al elaborării unui algoritm este transpunerea şi
execuţia automată a acestuia cu ajutorul calculatorului. Etapele de parcurs sunt
prezentate mai jos.
O primă fază constă în editarea programului în format sursă cu ajutorul unui
editor de texte propriu limbajului de programare sau extern.
Când se dispune de un compilator se parcurg următoarele faze:
- compilarea programului – constă în conversia unui program din limbajul
de programare de nivel înalt în care a fost scris (program sursă) într-un
limbaj apropiat de cel al calculatorului (program obiect);
- editarea de legături (link-editarea) – realizează legăturile între diferitele
module obiect şi soluţionează apelurile la funcţiile de bibliotecă referite
în program;
- execuţia programului – constă în parcurgerea pas cu pas şi efectuarea
operaţiilor specificate de codul de instrucţiuni, în limbaj maşină, de către
unitatea centrală a calculatorului.
PROBLEMĂ
Analiză, proiectare
OM
ALGORITM Programare
Editare
PROGRAM SURSĂ
PROGRAM SURSĂ
EDITAT
NU DA
Compilare
COMPILATO
R
Run
Program obiect
Linkeditare
Run
Execuţie sub Program
interpretor executabil
Execuţie
SOLUŢIE
17
IMPLEMENTAREA ALGORITMILOR
citeşte alfa
x : = 180* alfa / PI
Minfract: = (x-grade)*60
Minute: = trunc(minfract)
Secfract: = (minfract-minute)*60
secunde: = trunc(secfract)
Scrie
grade,minute,secunde
STOP
18
afişează rezultatele
Prin detalierea acestor acţiuni se obţine următoarea descriere în Pseudocod :
citeşte alfa
atribuie x 180* alfa / PI;
grade trunc (x);
minfract x-grade)*60;
minute trunc(minfract);
secfract(minfract-minute)*60;
secundetrunc(secfract)
scrie grade,minute,secunde
stop
Programul Pascal
Program conversie;
const
PI =3.14159;
cvgms =60;
cvrg =180;
var
alfa,x,minfract,secfract : real;
grade,minute,secunde : integer;
BEGIN{main}
{citire conversationala de date}
write(‘introduceti alfa in radiani’);
readln(alfa);
x:=alfa*cvrg/PI;
grade:=trunc(x);
minfract:=(x-grade)*cvgms;
minute:=trunc(minfract);
secfract:=(minfract-minute)*cvgms;
secunde:=trunc(secfract);
writeln(alfa:8:4,’radiani =’,grade:4,’grade ,minute:3,’minute’, secunde:3,
’secunde’);
END.
La conversia atât a gradelor în minute cât şi a minutelor în secunde se face
cu o înmulţire cu 60. Această valoare s-a introdus ca o constantă de conversie a
gradelor, minutelor, secundelor (cvgms). În acest mod programul a căpătat un
caracter mai general. Astfel, dacă se doreşte utilizarea programului pentru
conversii grade centesimale se va modifica numai această declaraţie de constantă.
La fel au fost tratate PI şi constanta de conversie a radianilor în grade (cvrg). Se
remarcă utilizarea la scriere a formatului.
19
De pe mediul de intrare se citesc 3 valori reale a,b,c, ce reprezintă
coeficienţii ecuaţiei de ordinul 2 : a * x2 + bx + c = 0. Să se calculeze
soluţiile ecuaţiei.
a) Descrierea şi semnificaţia structurilor de date folosite :
a : coeficientul lui x2
b : coeficientul lui x
c : coeficientul termenului liber
delta : b* b-4 * a * c
x : rădăcina ecuaţiei în cazul în care a=0 şi b<>0
x1,x2: rădăcinile reale ale ecuaţiei pentru delta>0
xR,xI: partea reală,respectiv imaginară a rădăcinilor pentru delta<0
b) Descrierea algoritmului în Pseudocod
Cea mai simplă formă a algoritmului este următoarea:
- citeşte conversaţional coeficienţii a,b,c
- calculează rădăcinile ecuaţiei în funcţie de coeficienţi
- scrie rezultatele
citeşte a,b,c
scrie a,b,c
dacă a=0 atunci
dacă b=0 atunci
dacă c=0 atunci
scrie’coef . a , b , c sunt zero’
altfel
scire’coef. a , b sunt 0 şi c <> 0’
_[]
altfel
atribuie xc/b
scrie x
_[]
altfel
atribuie delta b*b-4*a*c
dacă delta > 0 atunci
atribuie x1 (- b + sqrt delta)/2/a
x2 (- b - sqrt delta)/2/a
scrie x1,x2
altfel
dacă delta=0 atunci
atribuie x1 b/2/a
x2 x1
scrie x1,x2
altfel
atribuie xR -b/2/a
xI sqrt(-delta)/2/a
scrie xR,xI;xE,-x
20
_[]
_[]
_[]
stop
c) Programul Pascal
Program ecuatie2 ;
var a,b,c,x1,x2,xr,xi,x,delta:real;
BEGIN{main}
write(‘Coeficientii a,b,c?);
readln(a,b,c);
if a = 0 then
if b=0 then
if c=0 then
write(‘Coeficentii sunt 0’)
else
write (‘Coeficientii a si b sunt 0’)
else
begin {ec de gr I }
x:= - c / b ;
write(‘x’,x);
end
else
begin {ec de gr. II netriviala}
delta:=b*b-4*a*c;
if delta > 0 then
begin{rad reale distincte}
x1:=(( -b+sqrt(delta))/2*a);
x2:=(( -b-sqrt(delta))/2*a);
end;
else
write ( ‘x1=’,x1,’ ‘,’x2=’,x2);
begin {rad complex conjugate}
xR:= (-b/(2*a));
xI := (-sqrt (-delta)/2*a);
write(‘x1=’,xr,’+ i ‘,xi);
write(‘x2=’,xr,’- i ‘,xi);
end;
end;
END.
21
Dacă data este precizată prin tripletul(a,l,z)reprezentând anul,luna,ziua,se
observă că poziţia ei în an va fi data de zilele celor K=l-1 luni precedente(când
K>0) la care se adaugă cele z zile trecute din luna respectivă
Aflarea numărului de zile din primele K luni ale anului ridică unele dificultăţi
datorită faptului că lunile au numere
diferite de zile. START
25
t:= - t ;
end;
pi := 4 * s ;
writeln(‘valoarea lui PI=’,PI:10,8);
END.
NU
Scrie s
26STOP
c) Programul Pascal
Program sinus;
const EPS=0.001;
var
i : integer;
x,s,t : real;
BEGIN{main}
write(‘ x = ’); readln(x);
s := x ; t := - x ; i := 1 ;
repeat
i:=i+2;
t:= t * x * x / ( i * ( i – 1 ));
s:=s+t;
until abs(t)<=s*eps;
write(‘Sin(‘,x,’)=’,s);
END.
29
X,y : doi termeni consecutivi ai aproximării
N_max : numărulmaxim de iteraţii
c) Descrierea algoritmului în Pseudocod:
citeşte p,a,EPS,x0,n_max
atribuie x x0, i1 , y 1 / p ( ( p – 1 ) x + a / xp-1)
cât timp |y-x|>=EPS şi i<=n_max execută
atribuie x y ,
y 1 / p ( ( p – 1 ) x + a / xp-1),
i i+1
[]
scrie y,i
stop
Obs1. Valoarea lui x0 trrebuie să fie diferită de zero.Dacă dupăn_max
iteraţii nu s-a atins precizia EPS impusă,procesul de calcul se întrerupe tipărindu-se
aproximarea rădăcinii şi numărul de iteraţii
Obs2.Pentru calculul ridicării la o putere AB se folosesc funcţiile EXP şi LN
astfel că AB = EXP ( B * LN( A ))
d)Programul Pascal
Program radical_p;
var
n_max ,i,p : integer;
EPS,x0,a,x,y: real;
BEGIN{MAIN}
write(‘valoarea x0:integer;valoarea
EPS:real;valoarea :real;
n_max:integer ?’);
readln(x0,EPS,n_max);
i:=0;x:=x0;
y:=((p-1)*x+a/EXP((p-1)*LN(x)))/p;
while (abs(y-x)>=EPS)and
(i<=n_max)do
begin
x:=y;
y:= ((p-1)*x+a/EXP((p- 1)*LN(x)))/p;
i:=i+1;
end;
writeln(‘val. Radicalului =’,y:10:4,’
după’i:3,’iteraţii’);
END.
30
IMPLEMENTAREA ALGORITMILOR RECURSIVI
Citeste
a,b
p := a * b
a<b
x := a ,a := b
b := x
NU DA
b<>0
r:= a mod b
r<>0
a :=b, b := r
r := a mod b
cmmdc := b
cmmmc := p / b
cmmmc,cmmd
Scrie c
‘unul din termeni este
0’
STOP
33
c)Descrierea şi semnificaţia structurilor de date folosite
a,b : cele două numere întregi
cmmdc,cmmmc : variabile xîntregi pt.calculul cmmdc şi cmmmc
p : produsul celor două numere ( pentru calculul cmmmc)
x : variabilă auxiliară
d)Descrierea algoritmului în Pseudocod
citeşte a,b
atribuie p a * b { reţine produsul numerelor }
dacă a<b atunci
atribuie x a {schimbă cele două valori între ele}
ab
bx
[]
dacă b<>0 atunci
atribuie r a mod b {restul împărţirii întregi }
cât timp r<>0 execută
atribuie a b {pregăteşte o nouă reluare
a algoritmului }
br
r a mod b
[]
atribuie cmmdc b
cmmmc p / b
scrie cmmmc,cmmdc
altfel
scrie ‘ unul din termeni este zero’
[]
stop
c)Programul Pascal
Program Euclid;
var a,b,x,p,r,cmmdc,cmmmc:integer;
BEGIN{main}
write(‘introduceţi a si b : integer’);
readln(a,b);
p:=a*b;
if a<b then
begin
x:=a;
a:=b;
b:=x;
end;
if b<>0 then
begin
r:=a mod b;
34
while r<>0 do
begin
a:=b
b:=r;
r:=a mod b;
end;
cmmdc:=b;
cmmmc:=p div b;
writeln(‘cmmdc=’,cmmdc:8,
’cmmmc=’,cmmmc:9);
end
else writeln(‘unul din termeni este
zero’);
END.
36
Cu aceste observaţii algoritmul rafinat arată astfel:
citeşte n START
atribuie d 2
cât timp d<=(sqrt(n+0.5)) execută Citeste n
atribuie m0
cât timp n mod d =0 execută
d := 2
atribuie n n div d
mm+1 DA
d<=(sqrt(n+0.5))
[]
dacă m>0 atunci m:=0
scrie d , m
[] n mod d :=0
dacă d = 2 atunci
atribuie d 3 n :=n divd
altfel m := m + 1
NU
atribuie d d + 2 NU DA
m>0
[]
[] Scrie d,m
dacă n > 1 atunci
scrie n NU DA
d: = 2
[] n>1
stop d := 3 d:= d + 2
Scrie n
STOP
d)Programul Pascal
Program divizorii ;{descompunere în factori primi}
var n,d,m:integer;
BEGIN{main}
write (‘introduceti n:integer’);
readln(n);
writeln(n:4,’are urmatorii factori primi’);
writeln(‘factor’,’‘:5,’multiplicitate’);
d:=2;{cel mai mic numar prim}
while d<= trunc(sqrt(n+0.5)) do
begin
m:=0;
while(n mod d)= 0 do
begin
n:=n div d;
m:=m+1;
end;
37
if m>0 then
writeln(d:5,’ ‘:9,m:2);
if d = 2 then d:=3
else d:=d+2;
end;
if n>1 then writeln(n:5,’ ‘:10,’1’);
END.
Observaţie: S-a folosit indicarea de formă la afişarea unui şir de forma’ ‘:9,
care are ca efect lăsarea a 9 spaţii libere. Afişarea, de exemplu de 5 ori a
caracterului “a” nu se poate realiza prin “a”:5 ci prin instrucţiunile:
for i:=1 to 5 do write(‘a’);
În primul caz se va afişa un caracter a precedat de 4 spaţii libere.
38
referi la următoarele cifre din poziţiile simetrice prin cea mai semnificativă şi cea
mai puţin semnificativă cifră.
b) Descrierea şi semnificaţia structurilor de date folosite
n : numărul ce se verifică
p , q : cifrele cmps şi cms ale numărului
putere: întreg în care se calculează 10L-1
r : variabilă auxiliară
L : lungimea numărului
c) Descrierea în Pseudocod
O primă formulare a algoritmului este:
Citeşte n
Stabileşte lungimea L a numărului
Dacă L=1 atunci
Scrie ‘este palindrom’
Altfel
Repetă
Atribuie p c.m.s. cifră din n
q c.m.p.s cifră din n
suprimă c.m.s. şi c.m.p.s. cifră din n
atribuie L L-2
până p<>q sau L<2
[]
dacă p=q atunci
scrie ‘este palindrom’
altfel
scrie ‘nu este palindrom’
[]
[]
stop
Acţiunile de mai sus se pot rafina prin
- ‚atribuie q c.m.p.s. cifră din n’: atribuie q n mod 10
- ,atribuie p c.m.s. cifră din n’ : atribuie p n div 10
- ,suprimă c.m.p.s. şi c.m.s. cifră din n’ prin:
atribuie n n div 10
atribuie n n div 10L-1
Deoarece în Pascal nu există operator de ridicare la putere, se va înlocui în
algoritm L prin putere =10L-1.
Noua descriere în pseudocod devine:
Citeşte n
Determină putere=10l-1 {L fiind lungimea numărului}
Dacă putere=1 atunci
Scrie ‘este palindrom’
Altfel
Repetă
39
Atribuie p n div putere {separă c.m.s. cifră}
q n mod putere {separă c.m.p.s. cifră}
n n mod mare {suprimă c.m.s. cifră}
n n div 10 {suprimă c.m.p.s. cifră}
putere putere div 10
până (p<>q) sau (putere=10)
[]
dacă p=q atunci
scrie ‘este palindrom’
altfel
scrie ‘nu este palindrom’
[]
[]
stop
Acţiunea ,,determină putere =10L-1” se rafinează astfel:
Atribuie R n
Putere 1
Cât timp R>10 execută
Atribuie putere putere*10
R R div 10
d)Programul Pascal
Program pai;
type cifra= 0..9;
var
n,r,putere : integer;
p,q: cifra;
BEGIN{main}
write(‘n=’);readln(n);
r:=n;putere:=1;
while r>=10 do
begin
putere := 10 * putere;
r := r div 10;
end;
if putere = 1 then write(‘este ’)
else
begin
repeat
p := n div putere;
q := n mod 10;
n := n mod putere;
n := n div 10;
putere := putere div 100
until(p<>q)or(putere<10);
40
if p = q then write (‘este’)
else
write(‘nu este’);
end;
write(‘ palindrom’);
END.
Să se tabeleze funcţia:
41
x:=0;{valoarea limita inferioara}
while (x>=0) and (x<=10) do
begin
if x<1 then
f:=EXP(x-2)
else if x<2 then
f:=sin(x)+cos(x)
else
f:=0.5*LN(x+1);
writeln(x:2:2,' ':4,F:8:2);
x:=x+Dx
end;
end.
Fiind dat şirul de numere reale x1, x2,…, xn ş.a să se afle cel mai
mare element al şirului precum şi rangul sau (poziţia sa în şir). Dacă există
mai multe elemente în şir care ar avea valoarea maximă, se va reţin e
rangul primului maxim întâlnit de la stânga la dreapta.
a)Descrierea algoritmului în limbaj natural:
Fie CMAX variabila unde se va păstra valoarea maximă şi IR variabila în
care se va reţine
rangul primului START
maxim. Variabila I
numără (selecteză) Citeste n
elementele şirului.
Pentru început se i:=1
consideră că cel
mare element este NU
i:=i+1
DA
primul element al
şirului şi poziţia CMAX X1 , IR1 Citeste x[i]
sa este unică i:=i+1
(atribuie CMAX i:=2
x1,IR1).
Valoarea lui i<=n
CMAX şi a lui IR DA
NU CMAX <Xi
se schimbă în
cazul în care Y > Scrie CMAX, IR CMAX :=Xi,
xI, adică atunci IR:=1
când elementul
analizat (xi) este STOP i:=i+1
42
mai mare decât valoarea lui CMAX, caz în care se realizează: atribuie YXI,
IRI
Procesul de căutare a maximului şi a rangului se termină după analiza
ultimului element al şirului.
b)Descrierea şi semnificaţia structurilor de date folosite:
x: tabloul de numere reale (maxim 25)
n: dimensiunea efectivă a tabloului
CMAX, IR: elementul maxim şi poziţia sa
i: contor(întreg)
c)Descrierea algoritmului în Pseudocod :
citeşte n
pentru i=1,n,1 execută
citeşte xi
[]
atribuie CMAX X1 , IR1
pentru i=2,n,1 execută
dacă CMAX <Xi atunci
atribuie CMAX Xi, IR1
[]
[]
scrie CMAX, IR
stop
d)Programul în Pascal:
Program MAXIM_RANG;
Const Nmax = 25;
Var x : array [1..Nmax] of real;
I : 1..Nmax;
IR,N : integer;
CMAX: real;
BEGIN
Write(‘numarul de elemente’);
readln(n);
For i: = 1 to n do
Begin
Writeln(‘x[‘,i,’]=’);
readln(x[i]);
end;
CMAX : = x[1];
IR: = 1;
For i: = 2 to n do
If CMAX < x[i] then
begin
CMAX : = x[i];
IR: = i;
43
end;
Writeln(‘cel mai mare element este’, CMAX);
Writeln(‘pozitia sa este:’,IR);
End.
44
Se calculează cel mai mic dintre elementele şirului, numit MIN=min(x1,x2,…,xn)
şi-l plasăm în locul elementului x1, pe acesta ducându-l în locul unde s-a aflat cel
mai mic dintre elementele şirului.
Se obţine şirul: x1’,x2’,…,xn’
Se calculează: MIN = min(x1’,x2’,…,xn’)
şi se plasează în locul elementului x2’, iar pe acesta îl depunem în locul unde s-a
aflat cel mai mic dintre elementele şirului, obţinând şirul: x1’’,x2’’,…,xn’’
Se continuă raţionamentul până când şirul pe care îl analizăm are două
elemente, moment în care procesul de ordonare crescătoare s-a terminat.
Algoritmul de ordonare conform acestei metode:
- se execută n-1 paşi, cu j = 1,2,3,…,n-1
- la fiecare pas k:
- se determină poziţia j a elementului cel mai mic dintre elementele xi,
xi+1, ,xn
- se schimbă între ele valorile lui xi şi xj
Deci la fiecare pas se “selecteză” cel mai mic element dintre xi, xi+1,…,xn ,
motiv pentru care metoda se numeşte “sortare prin selecţie”.
b)Descrierea şi semnificaţia structurilor de date folosite:
x: tabloul ce se ordonează
n: dimensiunea efectivă a tabloului
temp: variabila de lucru(auxiliara)
i,j: contoare
k: poziţia elementului minim (relativ)
c)Descrierea algoritmului în Pseudocod:
citeşte n, (xi, j-1,n)
pentru i=1,n-1,1 execută
atribuie k i
pentru i=i+1,n,1 execută
dacă xk>xj atunci
atribuie k j
[]
[]
atribuie tempx
xkxi
xitemp
[]
scrie xi,i-1,n
stop
Soluţia 2 (“metoda prin interschimbare”)
a)Descrierea algoritmului în limbaj natural:
Se inspecteză perechi de elemente adiacente din şirul x, adică xI şi xi+1 pentru
i=1,n-1. Dacă xi<=xi+1 le lăsăm nemodificate, iar dacă xI>xi+1 atunci inversăm cele
2 valori.
45
Dacă se ajunge la capăt şi şirul nu este ordonat trebuie să se reia parcurgerea
şi inversarea până când şirul devine ordonat. De aceea se va lua o variabilă k care
va lua valoarea 1 ori de câte ori se inversează două elemente din şir. Iniţial
variabila k are valoarea zero. Procesul continuă până ce “indicatorul” k NU se mai
modifică.
b)Descrierea şi semnificaţia structurilor de date folosite:
x :tabloul ce se ordonează
n :dimensiunea efectivă a tabloului
temp:variabila de lucru(auxiliara)
i,j :contoare
k :indicator(flag)
c)Descrierea algoritmului în Pseudocod:
O primă variantă ar putea fi:
citeşte n
citeşte şirul x
ordonează şirul x
scrie şirul ordonat
stop
Operaţia “citeşte şirul x” implică citirea pe rând a fiecărui element din şir
pentru i=1,n,1 execută
citeşte x(i)
[]
Operaţia “ordonează şirul” poate fi detaliată
repetă
parcurgere şir
până şir ordonat
[]
Pentru condiţia “şir ordonat” se foloseşte o variabilă ”ORDONAT” cu valori
logice sau o variabilă întreagă “k” ce pot lua valorile:
Şir ordonat : ORDONAT = adevărat: k=0
Şir neordonat: ORDONAT = fals :k=1
În aceste condiţii “ordonează şir” devine :
repetă
atribuie ORDONATadevarat {k0}
parcurgere şir şi actualizează ORDONAT {K}
până ORDONAT {k=0}
[]
Operaţia “parcurge şir” constă în compararea succesivă a tuturor perechilor
de valori alăturate x(i) şi x(i+1). Deoarece sunt n-1 perechi operaţia se poate
detalia astfel:
pentru i=1,n-1,1 execută
compară x(i) cu x(i+1)
[]
46
Operaţia de interschimbare necesită 3 atribuiri:
atribuie tempx(i)
atribuie x(i)x(i+1)
atribuie x(i+1)x(i)
Astfel încât “compară x(i) cu x(i+1)” devine:
dacă x(i)>x(i+1) atunci
atribuie tempx(i)
x(i)x(i+1)
x(i+1)x(i)
atribuie ORDONATfals {k1}
[]
Operaţia “scrie şir ordonat” implică scrierea pe rând a tuturor elementelor
şirului, adică:
pentru i=1,n,1 execută
scrie x(i)
[]
Cu acestea algoritmul arată astfel:
citeşte n, (xi, i=1,n)
repetă
atribuie k0
pentru i=1,n-1,1 execută
dacă xi > xi+1 execută
atribuie tempxi
xixi+1
xi+1temp
atribuie k1
până k=0 []
[]
scrie xi, i=1,n
STOP
R4 R5 R8 R9
47
R6 R7
49
de-al doilea şir B. Dacă elementul comparat nu se află în şir, el se va adăuga şirului
D.
b) Descrierea şi semnificaţia structurilor de date folosite:
a, b: şirurile iniţiale
na, nb: dimensiunile efective ale celor două şiruri
d: şirul rezultat (reuniunea celor două şiruri)
i, j :contoare
k: indicator (flag):=1:condiţie îndeplinită
=0 :condiţie neândeplinită
c) Descrierea algoritmului în pseudocod:
citeşte nA, (ai,i=1,nA)
citeşte nB, (bi, I=nB)
pentru i=1,n, 1 execută
atribuie di ai
[]
atribuie nd na
pentru i=nb, 1 execută
atribuie k 0
pentru j=1,n , 1 execută START
dacă dj = bi atunci
atribuie k 1 Citeste nA si nB
dacă k=0 atunci
atribuie nd nd+1 i:=1
d b
nd I NU DA
i<=n1
[]
nd:=na di:= ai
[]
i:=iI+1
scrie nd, (di , I=1,nd)
stop i:=nb
i >0
Scrie nd k:=0
STOP j:=1
j<=n
NU dj = bi DA
i:=i-1
k:=1
50 NU k=0 DA
nd:=nd+1
d:=b
j:=j+1 nd := I
Variabila k devine egală cu I dacă elementului bi se găseşte în şirul D. Dacă
k=0, se va adăuga elementul bi şirului D, mărindu-se dimensiunea tabloului D.
În final se scrie numărul de elemente al şirului D şi elementele acestuia.
a)Programul Pascal este:
Program reuniune;
const nmax=20;
var
i,j,k:integer;
na,nb,nd:integer;
a,b,d:array[10..nmax]of integer;
BEGIN {citirea tablourilor}
write('introduceti na si nb');
readln(na,nb);
write('Introduceti elementele sirului a');
for i:=1 to na do read(a[i]);
write('Introduceti elementele sirului b');
for i:=1 to nb do read(b[i]); {introducerea sirului a in sirul d}
for i:=1 to na do d[i]:=a[i];
nd:=na; {testarea si introducerea daca este cazul a elementelor lui b in d}
for i:=1 to nb do
begin
k:=0;
for j:=1 to nd do
if d[j]=b[i] then k:=1; {elementulo bi se afla in sirul d}
if k=0 then
begin
nd:=nd+1;
d[nd]:=b[i] {adauga un nou element sirului d}
end;
end;
writeln('Sirul D are nd=',nd:4,' termeni');
writeln('elementele sirului D sunt:');
for i:=1 to nd do
write(d[i],' ');
END.
51
N copii identificaţi prin numerele 1,2,…,N, joacă următorul joc: se
aşează într-un cerc în ordinea 1,2,…N şi începând de la copilul K, numără
de la 1 la N, eliminând din cerc pe cel care a fost numărat N, eliminând din
cerc pe cel care a fost numărat N, ş.a.m.d. Folosind identificarea iniţială, să
se stabilească ordinea de ieşire a copiilor din joc.
a) Descrierea algoritmului în limbaj natural:
Într-un vector x se vor introduce numerele de ordine 1,2,…N, ale copiilor,
printr-o acţiune de forma:
Pentru i=1,n,1 execută
Atribuie ai i
Să se identifice poziţia copilului care trebuie să părăsească jocul, tipărindu-se
poziţia sa iniţială. Apoi se reface şirul x deplasându-se cu o poziţie la stânga toţi
copii din dreapta celui care a ieşit. Noul şir va avea cu o componentă mai puţin
(atribuie n n-1) după care procesul continuă la fel. Procesul se termină când a
ieşit din joc ultimul copil.
b) Descrierea şi semnificaţia structurilor de date folosite :
x: tablou în care se introduc copii
n: numărul de copii
k, n : caracteristicile jocului
s: numărul de ordine al copilului care”iese” din joc
c.) Descrierea algoritmului în pseudocod:
citeşte n {numărul de copii}
citeşte k,m
pentru i=1,n,1 execută {identifică copiii}
atribuie xi i
scrie xI
[]
atribuie S 0 {dă ordinea de ieşire din joc}
repetă
atribuie k (k-1+m) mod n
{selecteză poziţia copilului în şir}
atribuie S S+1
dacă k<>0 atunci
{este un copil din interiorul şirului}
scrie ‘copilul’,xk,’iese din joc al’ S,’-lea’
pentru i=k,n-1,1 execută
atribuie xi xi+1
altfel
{copilul care iese este al n-lea}
atribuie k 1
scrie ‘copilul’,xn,’iese din joc al ’,S,’-lea’
[]
atribuie n n-1 {restrânge şirul}
52
până n=1
[]
scrie ‘copilul’,x,’iese al ’,S+1,’-lea’
stop
Se remarcă folosirea operatorului ,,MOD” pentru selectarea ,,copilului care
părăseşte jocul”.
53
ALGORITMI. DE CAUTARE IN TABLOURI.
54
putem efectua căutarea mai eficient, oprindu-ne atunci când întâlnim un element
din şir care este mai mare decât y, deoarece în acest caz este clar că valoarea
căutată nu este în şir.
b) Descrierea şi semnificaţia structurilor de date folosite:
x : şirul (tabloul) în care se face căutarea
n : numărul de elemente al tabloului(dimensiunea efectivă)
y : valoarea ce se caută în tablou
i : contor
k : indicator( flag ) ; = 1 : condiţie îndeplinită ( y în şir )
= 0 : condiţie neîndeplinită
c)Descrierea algoritmului în Pseudocod
citeşte n , (xi , i = 1 , n ) , y
atribuie i 1, k 0
repetă
dacă xi = y atunci
atribuie k 1
scrie'elementul este în poziţia',i
altfel
atribuie i i + 1
[]
pînă k = 1 sau (xi > y) sau (i>n)
[]
dacă k =0 atunci
scrie ' elementul nu este în şir '
[]
stop
Soluţia 3
a)Descrierea algoritmului în limbaj natural:
În cadrul şirurilor ordonate, o metodă rapidă de căutare în şiruri este"metoda
de căutare binară" (logaritmcă). În cazul acestei metode se compară elementul xk
din mijlocul tabloului.
Sunt 3 situaţii posibile:
-xk = y -s-a găsit componenta dorită
-xk < y -componenta y se va căuta în jumătatea superioară a şirului
-xk > y -componenta y se va căuta în jumătatea inferioară a şirului.
Căutarea se încheie fie la găsirea valorii în şir, fie la restrângerea domeniului
de căutarela un singur element.
b)Descrierea şi semnificaţia structurilor de date folosite:
x : şirul (tabloul) în care se face căutarea
n : numărul de elemente al tabloului(dimensiunea efectivă)
y : valoarea ce se caută în tablou
i,j,k : indici în şir (capetele intervalului şi mijlocul)
N : indicator( flag ) ; = 1 : condiţie îndeplinită ( y în şir )
55
= 0 : condiţie neîndeplinită
c)Descrierea algoritmului în Pseudocod
citeşte n , (xi , i = 1 , n ) , y
atribuie i 1, j 0, N0
repetă
atribuie k[(i+j)/2]
dacă y = x atunci
atribuie Nk 1
altfel
dacă y < x atunci
atribuie jk k-1
altfel
atribuie i k+1
[]
[]
pînă N = 1 sau (i>j)
[]
dacă N=1 atunci
scrie ' elementul y este în şir în poziţia ', k
altfel
scrie ' elementul y nu este în şir '
[]
stop
56
citeşte (xi, i =1,n), (yi, i =1,n) {coordonatele punctelor}
citeşte a {abscisa punctului}
atribuie B0
pentru i =1,n,1 execută {realizează suma}
atribuie P1
pentru j = 1,n,1 executa {realizează produsul}
dacă i <> j atunci A-xi
atribuie P P*xi - xj
[]
[]
atribuie BB+yi * P
[]
scrie B
stop
citeşte n, (x,i=1,n)
57
atribuie ls 1,
poz 1, lc 1;
pentru i =1,n-1,1 execută
dacă xi < xi+1 atunci
atribuie lc lc+1
altfel
dacă lc > ls atunci
atribuie ls 1
pozi - lc+1
[]
atribuie lc 1
[]
[]
dacă lc > ls atunci
atribuie ls lc
pozn - lc+1
[]
scrie ls,poz
scrie xi, i = poz, poz + ls
stop
d)Programul Pascal;
Program subsir_1;
Const nmax=20;
Var
x : array [1..nmax] of real;
n,I :1..nmax;
lc,ls,poz:integer;
BEGIN{main}
write (‘n=’);read (n); {citeste elementele sirului}
for i:=1 to n do
begin
writeln(‘introduceti n’,i);
read(x[i]);
end; {stabileste lc,ls,poz }
lc:=1; ls:=1;poz:=1;
for i:=1 to n -1do
if x[i] < x[i+1] then
lc:=lc+1 {incrementeaza lungimea subsirului}
else
begin
if ls > lc then
begin {retine lungimea si pozitia subsirului cel mai lung}
ls := lc;
poz:= i- lc+1;
58
end;
lc:=1;
end;
if lc > ls then
begin
ls := lc;
poz:=lc+1;
end;
writeln(‘lungimea subsir maxim=’ , ls ,’pozitia=’,poz);
writeln(‘elementele subsirului cel mai lung sunt:’);
for i:=poz to poz + ls do
write(x[i]:4);
END.
Soluţia 2
a)Descrierea algoritmului în Pseudocod:
procedura subşir(n,xx,ls,poz) este :
atribuie ls1
poz1
lc1
pentru i=1,n-1,1 execută
dacă xxi<xxi+1 atunci
atribuie lclc+1
altfel
dacă lc>ls atunci
atribuie lsls
pozi-lc+1
[]
atribuie lc1
[]
[]
dacă lc>ls atunci
atribuie lsls
pozi-lc+1
[]
sfârşit{subşir}
citeşte n,(xi,i=1,n)
execută subşir (n,x, ls,poz)
scrie ls,poz
scrie (xi,i=poz, poz + ls - 1)
stop]
b)Programul Pascal:
Program subsir_2;
Const
nmax=20;
59
Type Sir: array [1..nmax] of real;
Dom:= 1 .. nmax;
Var
x: sir;
i,n,ns,poz,ls:dom;
PROCEDURE SUBSIR (n:dom;xx:sir; var ls,poz:dom )
var i,lc:dom;
begin
ls:= 1;lc:= 1; poz:=1;
for i:=1 to n-1 do
if xx[i] < xx[i+1] do
lc:=lc+1
else
begin
if lc>ls then
begin
ls:=lc;
poz:=i-lc+1;
end;
lc:=1;
end;
if lc>ls then
begin
ls:=lc;
poz:=n-lc+1;
end;
end;{subsir}
BEGIN {Programul principal}
write(‘n=’);
readln(n);
for i:= 1 to n do
begin
write (‘introduceti elementul x(‘,i:2,’)’);
readln (x[i]);
end;
SUBSIR (n,x,ls,poz);
Writeln(‘l subsir=’, ls,’pozitia din care incepe=’,poz);
Writeln(‘elementele subsirului sunt:’);
For i:= poz to poz + ls do
write(x[i]:4);
end.
60
ALGORITMI PENTRU POLINOAME
61
m,n,p,i,j :integer;
a,b,c:array [1..40] of integer;
BEGIN{main}
Write (‘dimensiunea polinoamelor=’);
readln(m,n);
Write(‘polinomul a=’);
For i:=1 to m+1 do
begin
Write(‘a[i]=’);
readln (a[i]);
end;
write(‘polinomul b=’);
For i:=1 to n+1 do
begin
Write(‘b[i]=’);
readln (b[i]);
end;
p:=m+n;
for i:=1 to p+1 do
c[i]:=0;
for i:=1 to p+1 do
for j:=1 to n+1 do
c[i+j-1]:= c[i+j-1] +a[i] *b[j];
writeln(‘polinomul produs=’);
for i:=1 to p+1 do
write(c[i]);
END.
Citeste m,n
a1,a2,…,am+1
b1,b2,…,bn+1
NU DA
m<n
i:=1 Scrie
’gradul deîmpărţitului<gradul împărţitorului’
NU DA
i<=m-n+1
ci := ai/bi
Scrie
c1,…,cm-n+1
j:=1
Scrie DA
am-n+2,…,am+1 j<=n+1
NU ai+j-1 ai+j-1+ ci + bj
STOP
j:=j+1
63
d)Programul Pascal:
Program impartire_polinoame;
Var
m,n,i,j,k,p: integer;
a,b,c,r : array [1..30] of real;
BEGIN{main}
Write (‘dimensiunea polinoamelor=’);
readln(m,n);
Writeln(‘polinomul deimpartit =’);
For i:=1 to m+1 do
read (a[i]);
Writeln(‘polinomul impartitor =’);
For i:=1 to n+1 do
read (b[i])
if m < n then
write(’gradul deîmpărţitului < gradul împărţitorului’)
else
begin
p := m-n;
writeln (‘gradul citului=’,p);
64
for i:= 1 to m-n+1 do
begin
c[i] := a[i] / b[i];
for j:=1 to n+1do
a[i+j-1]:= a[i+j-1] -c[i]*b[j];
end;
end;
writeln(‘polinomul cit=’);
for i:=1 to m-n+1 do
write(c[i]);
writeln;
writeln(‘polinomul rest=’);
for i:=1 to m-n+2 do
write(a[i]);
END.
68
pentru j = 1, p, 1 execută
scrie c(i,j)
[]
[] Detaliind operaţiile se ajunge la următorul algorim:
citeşte m,n,p
pentru i = 1, n, 1 execută
pentru j = 1, p, 1 execută
citeşte b(i,j)
[]
[]
pentru i = 1, n, 1 execută
pentru j = 1, p, 1 execută
citeşte b(i,j)
[]
[]
pentru i = 1, m, 1 execută
pentru j = 1, p, 1 execută
atribuie S0
pentru i = 1, p,1 execută
atribuie S S + a(i,k) * b(k,j)
[]
atribuie c(i,j) S
[]
[]
pentru i = 1, m , 1 execută
pentru j = 1, p, 1 execută
scrie c(i,j)
[]
[]
stop
d)Descrierea programului în PASCAL:
Program prod_mat;
Const
mmax = 10; nmax = 20;
pmax=30;
var
i,j,k,m,n,p: integer;
s : real;
a: array [1..mmax,1..nmax] of real;
b: array [1..nmax,1..pmax] of real;
c: array [1..mmax,1..pmax] of real;
BEGIN{main}
Write(“Dati valorile pentru m,n,p=”);
readln(m,n,p);
69
Writeln(‘Dati elementele matricei A’);
For i:= 1 to n do
begin
Writeln(‘Dati linia’, i:3, ‘:’);
For j:= 1 to n do
read(a[i,j]);
Readln;
end;
Writeln(‘Dati elementele matricei B’);
For i:= 1 to n do
begin
Writeln(‘Dati linia’, i:3, ‘:’);
For j:= 1 to p do read(b[i,j]);
readln;
End;
Writeln(‘calculeaza si tipareste matricea C’);
For i:= 1 to n do
begin {calculeaza o linie}
For j:= 1 to p do
begin {calculeaza un element}
S:=0;
For k:=1 to n do
s:=s + a[i,k]*b[k,j];
c[i,j]:= s;
end;
write(s:8:2); {scrie un element}
end;
END.
71
permută de i ori linia i
reintrodu linia
[]
pentru i = 1, m , 1 execută
pentru j = 1, p, 1 execută
scrie a(i,j)
[]
[]
stop
Operaţia ‘extrage linia i’ se realizează printr-un ciclu cu contor, prin care
elementele matricei A din linia i se introduc se introduc înnvectorul b, adică :
pentru k=1, n execută
atribuie b(k)a(i,k)
[]
Operaţia ‘permută de i ori linia i’ implică un ciclu cu contor în care
procedura permută este apelată de i ori, adică :
pentru j = 1, i, 1
execută permută (n,b)
[]
Operaţia ‘reintrodu linia’ implică introducerea elementelor vectorului b în
linia i din matrice prin:
pentru k=1, n execută
atribuie a(i,k)b(k)
[]
În aceste condiţii, algoritmul programului principal descris în procedură
arată astfel : citeşte m,n
pentru i = 1, m, 1 execută
pentru j = 1, n, 1 execută
citeşte a(i,j)
[]
[]
pentru i = 1, m, 1 execută
pentru k=1, m execută
atribuie b(k) a(i,k)
[]
pentru j = 1, i, 1
execută permută (n,b)
[]
pentru k=1, n execută
atribuie a(i,k)b(k)
[]
[]
pentru i = 1, m , 1 execută
pentru j = 1, p, 1 execută
72
scrie a(i,j)
[]
[]
stop
c) Programul PASCAL:
Program permuta_matrice;
Const
Nmax=10;
Type
linie = 1..nmax;
vector = array [linie] of real
Var
a : array [linie,linie] of real;
b : vector;
m,n:linie;
i,j,k: 1..nmax;
PROCEDURE PERMUTA (var x:vector; p: linie);
var
i: linie;
y:real;
begin
y:=x[p];
for i:= p downto 2 do
x[i]:= x[i-1];
x[1]:=y;
end;{permuta}
BEGIN {program principal}
read(m,n); {citeste dimensiunile tabloului}
for i:=1 to m do
for j:=1 to n do
read(a[i,j]);{citeste elementele matricei}
for i:=1 to m do
begin
for k:=1 to n do b[k]:=a[i,k];{extrage o linie din matrice}
for j:= 1 to i do permuta(b,n); {apeleaza permuta de i ori}
for k:=1 to n do a[i,k]:=b[k];{reintroduce lin i in matrice}
end;
for i:=1 to m do
begin
for j:=1 to n do
write(a[i,j]);
writeln;
end;
END.
73
O matrice rară, adică o matrice având majoritatea elementelor nule
(peste 90 %) se memorează economic sub forma a doi vectori, unul
conţinând elementele nenule din matrice, iar celălalt poziţiile lor în matrice,
făcând liniarizarea matricei pe linii. Să se definească oprocedură care
reconstituie o matrice rară A, având m linii şi n coloane şi p elmente
nenule, matricea este dată prin vectorii de componente nenule şi de
poziţiile acestora.
a) Descrierea algoritmului în limbaj natural:
Pentru matricea A de m = 3 linii şi n = 4 coloane, dată mai jos :
0 7,5 0 0
A= 0 0 -1,5 0
0 11 0 0
elementele ei se memorează sub forma a două tablouri în cadrul vectorilor :
val = (7.5, -1.5,11)
poz=(2,7,10)
unde tabloul val reţine valoarea elementelor matricei A nenule, iar tabloul poz
conţine poziţiile acestor elemente liniarizate pe linii.
Dacă elementul a(i,j) este diferit de 0, atunci potiţia sa în cadrul matricei sub
formă liniarizată are valoarea : Poz(k) = (i-1) * n + j unde k indică al
câtelea element nenul din matricea A este, i,j este numărul liniei, respectiv al
coloanei din matrice unde se află elementul al k- lea nenul, iar n numărul de
coloane al matricei date.
Dându-se cei doi vectori val şi poz şi ştiind că matricea A are m linii şi n
coloane, poziţia elementului nenul în matrice se află folosind relaţiile :
Linia i = [poz(k)/n] + 1
Coloana j = poz(k) mod n (1)
În aceste condiţii dându-se dimensiunile matricei de refăcut “m” şi ”n”,
numărul de elemente nenule din matrice şi cele două tablouri val şi poz se
iniţializează matricea A la zero după care folosind relaţiile (1) se calculează poziţia
elementelor nenule din matrice şi se asignează acestora valoarea din tabloul val.
Pentru rezolvarea problemei se va folosii o procedură de refacere a unei
matrici rare.
b)Descrierea şi semnificaţia structurilor de date.
p: numărul de elemente nenule din matricea A, nr. de elemente din val şi poz
val : tablou ce conţine elementele nenule din A
poz : tablou ce conţine poziţiile elementelor nenule din A
m,n : numărul de linii respectiv de coloane din matricea A
A : matricea rară cu m linii şi n coloane
b)Descrierea algoritmului în Pseudocod.
1)Descrierea procedurii.
Procedura refacemat (val,poz,p,m,n;A) este:
{se iniţializeză la 0 toate elementele matricii A}
74
pentru i = 1, m, 1 execută
pentru j = 1, n, 1 execută
atribuie a(i,j) 0
[]
[] {Se ia câte un element di vectorul val, respectiv poz şi se
calculează poziţia elementului în matricea A şi se atribuie acestuia}
pentru k = 1, p, 1 execută
atribuie i [poz(k)/n] + 1
atribuie j poz(k) mod n
atribuie a(i,j) val(k)
[]
sfârşit {refacemat}
2)Descrierea în Pseudocod a programului principal este :
citeşte m,n {numărul de linii şi coloane ale matricei A}
citeşte p {numărul de elemente nenule din matricea A}
pentru i = 1, p, 1 execută
citeşte val(i),poz(i) {elementele <> 0 ale lui A}
{şi poziţiile elementelor <> 0 ale lui A }
[]
execută refacemat (val,poz,p,m,n;A);
stop
2)Descrierea programului în PASCAL:
Program matrice_rara;
Const
nmax=10;
type
linie = 1..nmax;
matrice = array [linie,linie] of real;
vector = array [linie] of real;
pozitie = array [linie] of integer;
var
poz : pozitie;
val : vector;
a : matrice;
i,j,m,n,p : integer;
PROCEDURE REFACEMAT (val:vector; poz:pozitie; p,m,n: linie;var a: matrice);
var
i,j,k,: integer ;
begin {initializam matricea A cu 0}
for i:=1 to m do
begin
for j:=1 to n do
a[i,j]:=0;
75
end;
{determina linia si coloana elementului nenul din matrice}
for k:= 1 to n do
begin
I:= poz[k] div n + 1;
j:= poz[k] mod n;
a[i,j]:= val[k];
end;
end; {reface matricea}
BEGIN{main}
Read(m,n);
Read(p);
for i:=1 to p do
read(val[i]);
for i:=1 to p do
read(poz[i]);
refacemat(val,poZ,m,n,p,a);
for i:=1 to m do
begin
for j:=1 to n do write(a[i,j] :8:2);
writeln;
end;
END.
………………\
a1n…………………….an n
a)Descrierea algoritmului în limbaj natural:
Se dă dimensiunea n a matricei. Se observă că avem de parcurs în sens orar
n/2 (pentru n par), respectiv [n/2] + 1 (pentru n impar)
akk…………………………. ak,n-k+1
79
ALGORITMI PENTRU STUDIUL LEGILOR DE
COMPOZIŢIE
80
stop
Varianta 2:
Se prezintă şi o altă variantă, în care testul aiRaj şi ajRak
se face prin compararea produsului A(i,j) * A(j,k) cu zero.
citeşte n,(a[ij], i=1,n; j=1, n)
atribuie T 0
pentru i = 1, n execută
pentru j = 1, n execută
dacă (i<>j )atunci
pentru k = 1, n execută
dacă (k<>i şi k<>j şi
a(j,k)*a(i,j)=1)atunci
dacă (a(i,k)<>1)atunci
atribuie T 1
[]
[]
[]
[]
[]
[]
dacă T=0 atunci
scrie ‘relaţia este tranzitivă’
altfel
scrie ‘relaşia este tranzitivă’
[]
stop
[]
[]
[]
[]
dacă T=0 atunci
scrie ‘relaţia este asociativă
altfel
scrie ‘relaţia nu este asociativă
[]
stop
90
a) Descriere:
PROCEDURE Substring(Şir: String;startpos,num:IndexRange;
Var subşir : string; var error:boolean)
b) Definire intrări / ieşiri:
Intrări :Şir - şirul original
StartPos - poziţia de început
Num - numărul de caractere ale subşirului
Ieşiri : SubŞir - Subşirul de "Num" caractere începând din poziţia
"StartPos"
Error - indicator de eroare : subşirul nu face parte din şirul original
c) Descrierea în Pseudocod:
poziţionează indicatorul de eroare în funcţie de intrări
dacă not error atunci
pentru pos = 1 , Num , 1 execută
atribuie SubŞir.Chars[pos] Şir.Chars[StartPos+Pos+1]
[]
umple restul subşirului cu blancuri
atribuie SubŞir.Length Num
[]
d) Implementarea în Pascal:
Procedure SubString(Sir:String;StartPos,Num:IndexRange;
Var SubSir:String;Var error : boolean)
Var Pos: IndexRange;
Begin { Sub String }
Error:= StartPos+Num-1>Sir.Length;
if not error then begin { not error }
for pos:=1 to Num do
SubSir.Chars[pos]:=Sir.Chars[StartPos-1];
for pos:=Num+1 to MaxLength do
SubSir.Chars[pos]:= ' ';
Subsir.Length:=Num
end; { not error }
end; { SubString}
3.Operaţia CONCAT
a) Descriere:
Procedure CONCAT(var Sir1:String;Sir2:String;Var error:boolean);
b) Definire intrări / ieşiri:
Intrări : Sir1 - primul şir
Sir2 - al 2-lea şir
Ieşiri Sir1 - concatenarea celor 2 şiruri
Error - Dacă lungimea totală > MaxLength
c) Descrierea în Pseudocod
calculează lungimea totală
91
atribuie errorlungimea totală>MaxLength
dacă not error atunci
atribuie LastPoslungimea Sir1
pentru pos=1,lungimea Sir2 , 1 execută
atribuie LastPosLastPos+1
atribuie Sir1.Chars[LastPos]Sir2.Chars[pos]
[]
[]
atribuie lungimea Sir1 LastPos
d) Implementarea în Pascal:
procedure CONCAT(var Sir1:String;Sir2:String;var error:boolean);
var Len,Pos,LastPos:IndexRange;
begin{Concat}
len:=Sir1.Length+sir2+length;
error:=len>maxlength;
if not error then begin
LastPos :=Sir1.Length;
for : pos :=1 to Sir2>Length do begin
Lastpos:=Lastpos+1
Sir1.Chars[LastPos]:=Sir2.Chars[pos];
End;
Sir1.Length:=lastPos;
End;{not error}
End;{Concat }
4. Operaţia DELETE
a) Descriere:
Procedure Delete ( var sir : String; pos,num:IndexRange;var error:boolean);
b) Definire intrări / ieşiri
Intrări Sir - şirul din care se şterge
Pos - poziţia din care se şterge
Num - numărul de caractere de şters
Ieşiri : Sir - noul şir
Error - semnalizează că subşirul ce se şterge este / nu este în
interiorul şirului dat
Se vor folosi procedurile deja scrise : SubString şi Concat
c) Descriere în PSEUDOCOD
calculează poziţia ultimului caracter ce se şterge
error este True dacă ultima poziţie nu e în şir
dacă not error atunci
extrage subşirul de la dreapta părţii ce se şterge
extrage subşirul de la stânga părţii ce se şterge
concatenează cele 2 subşiruri
[]
92
d) Implementarea în Pascal
Procedure delete(var sir:string;pos,num:IndexRange;
Var error : boolean );
Var sir1:string;
Lastpos:indexrange;
Suberror:boolean;
begin { Delete }
lastpos:= pos+num-1;
error :=lastpos>sir.length;
if not error then begin
substring(sir,sir1,lastpos+1,sir,length-lastpos,suberror);
substring(sir,sir,1,pos-1,suberror);
concat(sir,sir1,suberror);
end;
end;{delete}
5.Operaţia Insert
a) Descriere:
Procedure Insert(var sir :string;sir1:string;pos:indexrange;var
erroe:boolean);
b) Definire intrări/ieşiri:
Intrări : sir - şirul în care se inserează
sir1 - şirul care se inserează
pos - poziţia de unde se inserează
Ieşiri: sir - şirul iniţial în care a fost inserat sir1
error - testează dacă pos este în interiorul şirului iniţial şi dacă
lungimea şirului nou > MaxLength
Se folosesc din nou procedurile deja scrise Substring şi Concat
c) Descrierea în Pseudocod:
atribuie error (pos>lungime sir) sau ( lungimea totală > MaxLength)
dacă not error atunci
extrage subşirul ce începe din poziţia în care se inserează
extrage subşirul ce precede poziţia în care se inserează
concatenează cu sirul sir1
concatenează rezultatul cu primul subsir extras
[]
d) Implementarea în Pascal
Procedure insert(var sir : String; sir1:String; pos: IndexRange;
var error: boolean)
var SirTemp : String;
Suberror : Boolean;
Begin {insert }
Error:=(pos> Sir.Length)or(Sir.Length+Sir1.Length>MaxLength);
If not error then begin
Substring(Sir,sirtemp,pos,sir.length-pos+1,suberror);
93
Substring(sir,sir,1,pos-1,suberror);
Concat(sir,sir1,suberror);
Concat(sir,sirtemp,suberror);
End;
End;{insert}
6.Operaţia Search
a) Descriere:
Procedure Search(sir,subsir:string;var found:boolean;
var pos:indexrange;var error:boolean);
b) Definire intrări/ieşiri
Intrări : sir - sirul în care se caută
Subsir-şirul ce se caută
Ieşiri : Found- semnalizează găsirea/negăsirea subşirului căutat
Pos - dacă se găseşte poziţia în care se află subşirul căutat în şir
Error - semnalizează şiruri vide sau lungimea subşirului ce se caută
este > lungimea şirului în care se caută
c) Descrierea în Pseudocod :
O primă variantă a algoritmului este:
- se caută apariţia primului caracter din subşir
- dacă nu apare atunci nu există
- dacă apare atunci vom continua cu apariţia celorlalte caractere
- dacă le găsim pe toate căutarea se termină cu succes
- dacă se întâlneşte un caracter ce nu se potriveşte ne întoarcem la început
- procesul se opreşte la succes sau atunci când numărul caracterelor
rămase de verificat este mai mic decât lungimea subşirului ce se caută.
Prin rafinarea enunţurilor nestandard ,algoritmul devine :
atribuie error (sirurile sunt de lungime 0) sau (subşirul > şirul în care se
caută)
dacă not error atunci
atribuie foundfalse;încătrue;PosCrt1;
cât timp mai e de căutat şi încă nu s-a găsit execută
dacă primul car în Subşir=car din poziţia crt atunci
verifică restul SubSir cu următoarele poz în Sir
altfel incrementează poziţia crt în Sir
[]
atribuie încă (mai sunt posibilităţi de verificare)şi
(mai sunt caractere în Sir)
[]
dacă s-a terminat căutarea cu succes atunci
atribuie pospoziţia crt din Sir
[]
d) Implementare în Pascal :
procedure Search(sir,subsir:string;varfound:boolean;
var pos:indexrange;var error:boolean);
94
var stpos,subpos:indexrange;
match,inca:boolean;
begin {Search }
error:=(sir.length=0)or(subsir.length=0)or(sir.length<subsir,length);
if not error then begin
stpos:=1;
found:=false;inca:=true;
while inca and not found do begin {inca}
if subsir.chars[1]=sir.chars[stpos]then begin
subpos:=1
match:=true;
while(subpos<subsir.subsir.length)and match do
if subsir.chars[subpos+1]=sir.chars[stpos+subpos]
then subpos:=subpos+1
else begin
match:=false;
stpos:=stpos+1
end;
found:=match;
end
else stpos:=stpos+1;
inca:=(stpos+subsir-1)<=sir.length
end{inca}
if found then pos:=stpos;
end{not error}
end;{search}
98
dacă numărul vocalelor distincte >=3 atunci incrementează numărul
cuvintelor
[]
până la sfârşitul fişierului
[]
tipăreşte numărul cuvintelor
Pentru detalierea acţiunilor mai importante se fac câteva observaţii:
1)Se prezintă o variantă pentru dialeatul Pascal implementat sub sistemul de
operare MIX, de pe minicalculatoarele tip Independent I 102F/4M, sau
compatibile.
2)Numele fişierului din care se citeşte textul este memorat într-o variabilă de
tip:
packed array[1..max_name]of char; datorită faptului că operaţia de citire a
valorilor unor astfel de variabile permite citirea într-o singură operaţie a ei (nu
ciclat pentru fiecare caracter ce o alcătuie
Max_Name este o constantă aleasă astfel încât să poată fi memorat cel mai
lung nume valid de fişier. Se ştie că acesta poate fi: "nnnnnnnnn.ttt;vvv"
unde: nnnnnnnnn - numele,maxim 9 caractere
ttt - tipul,maxim de 3 caractere
vvv - versiunea,maxim 3 caractere
astfel încât : Max_Name=17;
3)În exploatarea fişierelor se va folosi o variabilă de tip "integer"pentru a
detecta erorile la deschiderea fişierelor.Ovaloare=-1 a acestei variabile va indică
eşecul operaţiei de deschidere a fişierului respectiv.
4)Detalierea operaţiei de testare de sfârşit de fişier impune şi refacerea citirii
din fişier pentru a testa apariţia sfârşitului de fişier.
d) Programul Pascal;
Program vocale ;
Label 13;
const Max_Name=17;
type file_name=packed array[1..max_name]of char;
multime=set of char;
var fis :text;
nume :file_name;
ncuvine,nvocale:integer;
mvocale:multime;
car :char;
gata :boolean;
cod_open:integer;
BEGIN {main}
write('Numele fisierului text:');readln(nume);
reset(fis,nume, ,cod_open);{atentie la parametrii !}
if cod_open= -1 then
begin
99
writeln('Eroare deschidere fişier!');
goto 13;
end;
ncuvinte:=0;
repeat
mvocale:=[]{multimea vocalelor din cuvant -vida}
nvocale:=0;
gata:=false;
while not gata do
if eof(fis) then gata:=true
else
begin {in fisier}
read(fis,car);
if eoln(fis) then
begin {sfarsit de linie}
readln(fis);
gata:=true;
end
else
begin {caracter normal}
if car in['.',',',';',' '] then gata:=true
else
if not (car in ['A'…'Z','0'…'9'])then
writeln('caracter nepermis');
else
if car in(['A','E','I','O','U']- mvocale )then
begin
mvocale:=mvocale+[car];
nvocale:=nvocale+1;
end;{caracter normal}
end;{sfarsit de linie}
end;{in fisier}
if nvocale>=3 then nvocale:=nvocale+1;
until eof(fis);
writeln('Nr. cuvintelor cu prop. ceruta :' , ncuvinte:8);
13 :
END.
TIPUL ÎNREGISTRARE
112
Operaţia “ordonează medie şi vector poziţii ” implică ordonarea tabloului y,
cu inversările corespunzătoare ale elementelor tabloului x, adică:
repetă
atribuie k 0
pentru i = 1, n-1, 1 execută
dacă y[i] < y[i+1]atunci
atribuie s y[i], y[i] y[i+1], y[i+1] s
m x[i], x[i] x[i+1], x[i+1] m
k 1
[]
[]
până k=0
[]
Întrucât tabloul de înregistrări ’grupa nu a fost modificat prin ordonare, ci
doar tabloul x cu poziţiile studenţilor astfel încât prima componentă a acestuia
conţine numărul de ordine al studentului cu media cea mai mare, operaţia ‘scrie
tablou ordonat’, implică:
- selectarea pe rând a componentelor tabloului x prin:
atribuie m x[i]
- scrierea câmpurilor nume, note şi medie ale componentei grupa [nr], prin
secvenţa:
pentru i = 1, n, 1 execută
atribuie m x[i]
pentru j = 1, 15, 1 execută
scrie grupa[m] . nume[j]
pentru j = 1, 15, 1 execută
scrie grupa[m] . note[j]
[]
[]
scrie grupa[m] . medie
[]
d)Programul Pascal:
Program grupa;
Const
nmax=30;
type stud = record
nume: array [1..15] of char;
note: array [1..6] of integer;
medie: real;
end;
var
grupa : array [1..nmax] of stud;
y : array [1..nmax] of real;
x : array [1..nmax] of integer;
113
s : real;
i,j,n,m:integer;
BEGIN{main}
Write(’n=’); readln(n);
for i:=1 to n do
with grupa[i] do
begin
for j:=1 to 15 do
read(nume[j]);
S:=0
for j:=1 to 6 do
begin
read(note[j]);
S:=S + note[j];
end;
S:=S/6;
end;
for i:=1 to n do
begin
y[i]:= grupa[i]. medie;
x[i] := 1
end;
repeat {ordonare}
k:=0;
for i:=1 to n-1 do
if x[i]< x[i+1] then
begin
s := y[i];
y[i] := y[i+1];
y[i+1] :=s;
m := x[i];
x[i] := x[i+1];
x[i+1] :=m;
k :=1;
end;
until k :=0;
for i:=1 to n do
begin {scrie tabel}
m:= x[i];
with grupa[m] do
begin
for j:=1 to 15 do
write(nume[j]);
for j:=1 to 6 do
114
write(note[j]);
S:=S + note[j];
Writeln(medie:6:2);
end;
end;
END.
116
Function localizare (nech: nume echipă):poziţie;
unde tipul poziţie este declarat ca un subdomeniu prin:
Type poziţie = 1..nr echipe
În urma actualizării clasamentuli, acesteatrebuie sortat în ordinea
descrescătoare a punctajului,( la punctaj egal se va folosi criteriul golaveraj), asfel
încât acţiunea ‘afişare clasament’ se detaliază în :
-sortare clasament dupăpuncttaj şi golaveraj
-afişare tablou ordonat
Sortarea tabloului clas se va face prin metoda contorizării inversărilor.
Programul va fi structurat pe proceduri, câte una pentru fiecare acţiune a
algoritmului
b)Programul Pascal arată astfel:
Program fotbal;
Const
Nr.echipe=18;
Nr.jocuri=34;
Pctaj max=68;
Type
Nume echipe = array[1..10] of char;
Pozitie = 1..nrechipe;
Echipa = record
Nume:nume echipa;
Jucat, vict,pierd,
egal : 0.. nrjocuri;
Puncte: 0..pctajmax;
Gtmarc,gtprim: integer;
end;
clasament = array [pozitie] of echipa;
var
rezultat : (victorie, egalitate, pierdere);
clas: clasament;
PROCEDURE CITNUME (var ne : nume echipa);
var i:= 1..10;
begin
For i:=1 to 10 do read(ne[j]);
end; {citnume}
PROCEDURE CITCLASAMENT;
var i: pozitie;
begin
For i:=1 to nrEchipe do
With clas[i] do
begin
CitNume(nume);
Read(jucat,vict,pierd,egal,puncte);
117
Readln(gtmarc,gtprim);
end;
End; {citclasament}
PROCEDURE ACTUALIZARE;
Var
ne:nume echipa;
j:integer;
p1,p2:pozitie;
q1,q2:0:maxint;
begin {actualizare}
for j:= 1 to nrEchipe div 2 do
begin
citNume(ne); read(q1);
p1:= localizare(ne);
citNume(ne); read(q2);
p2:= localizare(ne);
{determinarea tipului rezultatului}
if q1 > q2 then
rezultat:= victorie
else
if q1< q2 then
rezultat :=pierdere
else
rezultat :=egalitate;
{actualizare nr. partide jucate}
whith clas[p1] do
begin
jucat:= jucat+1;
gtmarc:= gtmarc+q1;
gtprim:= gtprim+q2;
end;
whith clas[p2] do
begin
jucat:= jucat+1;
gtmarc:= gtmarc+q2;
gtprim:= gtprim+q1;
end;
{actualizare victorii pierderi punctaj}
case rezultat of
victorie : begin
whith clas[p1] do
begin
vict:= vict+1;
puncte:= puncte+2;
118
end;
whith clas[p2] do
begin
pierd:= pierd+1;
end;
pierdere: begin
whith clas[p2] do
begin
vict:= vict+1;
puncte:= puncte+2;
end;
whith clas[p1] do
begin
pierd:= pierd+1;
end;
egalitate: begin
whith clas[p1] do
begin
egal:= egal+1;
puncte:= puncte+1;
end;
whith clas[p2] do
begin
egal:= egal+1;
puncte:= puncte+1;
end;
end;
end;{case}
end;{actualizare}
FUNCTION LOCALIZARE
(nech:numeEchipa):pozitie;
var i : pozitie;
begin
i:=1;
While clas[i].nume <>nech do
i:=i+1;
localizare:=i;
end; {localizare}
PROCEDURE SORTARE;
(dupa punctaj si golaveraj)
var i: pozitie;
j: 1..10;
Var i: pozitie; ech: echipa;
Begin
119
Repeat
ninv:= 0;
for j:= 1 to nrEchipe -1 do
if (clas[i].puncte< clas[i+1].puncte) or
(clas[i].puncte= clas[i+1].puncte) and
(clas[i].gtmarc - clas[i].gtprim) <
(clas[i+1].gtmarc- clas[i+1].gtprim) then
begin
ninn:= ninv+1;
ech:= clas[i];
{toate campurile inregistrarii}
clas[i]:= clas[i+1];
clas[i+1]:= ech;
end;
until ninv=0;
end; {sortare}
PROCEDURE ASFISCLASAMENT;
begin {afisclasament}
Sortare;
Writeln(‘ ‘ : 10, ‘jocuri vict pierd
egal pcte’);{captabel}
for i:= 1 to nrEchipe do
whith clas[i] do
begin
for j:= 1 to 10 do
write (nume[j]);
writeln(‘ ‘:4,jucat:2,’ ‘:3
,vict:2, ‘ ‘:4,pierd:2‘:3,
egal:2,‘ ‘:3,puncte:2);
end;
end;{afisclasament}
BEGIN {main}
citclasament;
actualizare;
afisclasament;
END.
120
laturi ale triunghiului şi se trece la utilizarea metodei de construcţie geometrică,
metodă acre implică următorii paşi:
a) Se trasează două mediatoare;
b) Sedetermină punctul lor de intersecţie;
c) Se determină raza cercului circumscris ca distanţa între punctul de
intersecţie al mediatoarelor şi oricare din punctele date;
d) Se trasează cercul cu centrul determinat la punctul b) având raza
determinată la ounctul c).
Trasarea unei mediatoare a unui segment presupune:
- trasarea a două cercuri cu centrele în capetele segmentului, având aceeaşi
rază (mai mare decât jumătatea segmentului)
- intersectarea celor două cercuri şi determinarea ecuaţiei coardei comune
reprezentând mediatoarea
Intersecţia a două drepte:
(D1): a1*x + b1*y + c1 = 0, şi
(D2): a2*x + b2*y + c2 = 0
are coordonatele:
x=-(c1*b2 – c2*b1)/(a1*b2 – a2*b1)
y=-(c1*a2 – c2*a1)/(a1*b2 – a2*b1)
Ecuaţia dreptei de intersecţie a cercurilor
C1(x1,y1,r1) şi
C1(x2,y2,r2)
este:
x*(x1-x2) + y*(y1-y2) + (r12 – x12 – y12 – (r22 – x22 – y22))=0
În final după afişarea tipului de obiect rezultat se trsează triunghiul,
cercurile, dreptele de intersecţie şi cercul circumscris.
b)Descrierea şi semnificaţia structurilor de date folosite:
Elementele geometrice: cercuri, drepte, puncte de intersecţie (ale
cercurilo ale mediatoarelor) sunt descrise prin tipul înregistrare:
Type forma = (nimic,punct,linie,cerc);
Figura = record
Case disc :forma of
Punct(poziţie:coord);
Linie: (a,b,c: real);
Cerc : (centru: coord;raza: real);
End;
Varianta nimic a fost prevăzută pentru cazul în care construcţia geometrică
nu este posiobilă (punctele sunt colineare).
Variabilele p1,p2,p3,c1,c2,c3,d1,d2,p0, cerc sunt înregistrări de tip figură şi
reprezintă coordonatele punctelor date, coordonatele centrelor cercurilor, punctele
de intersecţie al cercurilor, p0 punctul de intersecţie al dreptelor D1,D2 şi
coordonatele centrului cercului circumscris.
Procedura citpct asigură citirea coordonatelor unui punct şi definirea tipului
obiectului- punct.
121
Procedura tipfig realizează afişarea tipului obiectului de afişat împreună cu
formaţiile aferente.
Procedura distanţă determină distanţa dintre două puncte.
Procedura trascerc stabileşte tipul obiectului cerc: raza şi coordonatele
centrului cercului.
Procedura intersdr determină coordonatele punctului de intersecţie a două
drepte x şi y specificând şi tipul obiectului.
Procedura iterscerc realizează dreapta de intersecţie a două cercuri.
Procedura draw asigură trasarea unei drepte
Funcţia identic verifică dacă punctele sunt confundate
c)Descrierea algoritmului în Pseudocod:
O primă variantă a algoritmului implică:
*citeşte coordonate puncte
dacă puncte confundate atunci
scrie puncte confundate
altfel
determină componentele cercului circumscris
[]
afişează grafic stop
Operaţia ‘citeşte coordonatele puncte’ implică apelul procedurii citpct astfel:
Execută citpct(p1)
Execută citpct(p2)
Execută citpct(p3)
Acţiunea ‘determină componentele cercului circumscris’poate fi descrisă
prin apelul procedurilor
Alege raza R
Execută trancec(P1,R,C1);
Execută trancec(P2,R,C2);
Execută trancec(P3,R,C3);
Execută interscerc(C2,C3,D1);
Execută interscerc(C3,c1,D2);
Execută interscerc(C3,C2,D2);
Execută intersdr(D2,D2,P0);
Execută distanţa(P2,P0,Raza);
Execută trascerc(P0,Raza,C);
Execută tipfig;
O alegere corespunzătoare a razei R care să depăşească jumătate oricărei
laturi a triunghiului o reprezintă semisuma a două laturi ale triunghiului.
Operaţia ’afişează grafic’ implică iniţializarea sistemului grafic, trasarea
triunghiului a cercurilor, a punctelor de intersecţie a cercurilor şi dreptelor şi a
cercului circumscris, urmărindu-se metoda geometrică.
d)Programul Pascal arată astfel:
Program cercuri;
Uses graph;
122
Type
Forma= (nimic,punct, linie,cerc);
Coord=record
x,y:real;
End;
Figura=record
Case disc:forma of
Nimic:( );
Punct: (poz:cord);
Linie: (a,b,c:real);
Cerc: (cen:cord;raza:real);
End;
Var
P1,p2,p3,c1,c2,c3,d1,d2,p0,ccirc:figura;
r,rcirc:real;
gd,gm:integer;
procedure citpct (var p;figura);
begin
with p.poz do begin
disc:=punct;
read(x,y);
end;
end;
Procedure tipfig(f:figura);
Begin
With f do
Case disc of
Nimic:write(‘fig nula’);
Punct:with poz do write (‘punct(’,x,y’)’);
Linie:write(‘dreapta’,a,b,c);
Cerc: with cen do
Write(‘cerc’,x,y’raza’,raza);
End;
End;
Function distanta(f1,f2:figura):real;
Begin
If (f1.disc=punct) and (f2.disc=punct) then
Distanta:= sqrt(sqtr(f1.poz.x- f2.poz.x)+ sqtr(f1.poz.y-
f2.poz.y))
Else
Distanta:=0
End;
Procedure transcerc (p:figura;r:real;var c:figura);
123
Begin
With c do
If (p.disc=punct) and (r>0) then begin
Disc:=cerc;
Cent:=p.poz;
Raza:=r
End;
Else
Disc:=nimic;
End;
Procedure intrsdr(d1,d2:figura; var p:figura);
Var
Det:real;
Begin
If (d1.linie=linie) and (d2.linie=linie) then begin
Det:=d1.a*d2.b- d1.b*d2.b;
If abs(det)<1.Oe-6 then
p.disc:= nimic
else
with p do begin
disc:= punct;
with poz do begin
x:= -(d1.c*d2.b- d1.b*d2.c)/det;
y:=+(d1.c*d2.b- d1.b*d2.c)/det
end;
end;
end;
else
p.disc:= nimic;
end;
Procedure interscerc (c1,c2: figura; var d:figura);
Begin
If (c1.disc=cerc) and (c2.disc = cerc) then
With d do begin
Disc:=linie;
a:= (c1.cen.x – c2.cen.x);
b:= (c1.cen.y – c2.cen.y);
c:= ((sqr(c1.raza)-(c1.cen.x)-sqr(c1.cen.y))-
sqr(c2.raza) + sqr(c2.cen.x) + sqr(c2.cen.y)/2.0
end;
else
d.disc:= nimic
end;
Function identic (f1,f2: figura) : boolean;
124
begin
identic:=distanta (f1,f2)< 1.Oe-6
end;
Procedure draw (f: figura);
Var
x1,y1,x2,y2: integer;
begin
if(f.disc=linie) then
if (f.b=0) then {linie verticala}
linie(trunc(-f.c/f.a),0,trunc(-f.c/f.a), getmaxy
else (f.a=0) then {linie orizontala}
linie(0,getmaxy - trunc(-f.c/f.b), 640,
getmaxy - trunc(-f.c/f.b))
else begin{linie intre 2 puncte ce se calculeaza:}
{P1(0,d1(0)) si P2(640,d1(640))}
x1:=c;
y1:=trunc (-(f.c/fb));
x2:=640;
y2:=trunc(-(f.c +f.a*x2)/f.b);
linie(x1,getmaxy – y1,x2,getmaxy – y2);
end;
end;
Begin {main}
Citpct(P1);
Citpct(P2);
Citpct(P3);
If identic (P1,P2) or identic (P2,P3) or identic (P3,P1) then
writeln (‘puncte confundate’)
else begin
r:=(distanta(p1,p2) + distanta(p2,p3))/2;
trascec(p1,r,c1);
trascec(p2,r,c2);
trascec(p3,r,c3);
interscerc(c2,c3,d1);
interscerc(c3,c1,d2);
intrsdr(d1,d2,p0);
rcirc:= distanţa(p1,p0);
trascerc(p0,rcirc,ccirc);
tipfig(ccirc);
end;
{initializare sistem grafic}
readln;
gd:=detect; gm:=2;
initgraph(gd,gm, ‘c:\tp\’);
125
if graphResult <> grOk then halt(1); {eroare de initializare}
{desenare}
linie(trunc(p1.poz..x), getmaxy – trunc(p1.poz.y),
trunc(p2.poz..x), getmaxy – trunc(p2.poz.y);
linie(trunc(p3.poz..x), getmaxy – trunc(p3.poz.y),
trunc(p2.poz..x), getmaxy – trunc(p2.poz.y);
linie(trunc(p3.poz..x), getmaxy – trunc(p3.poz.y),trunc(p1.poz..x),
getmaxy – trunc(p1.poz.y);
setcolor(blue);
circle(trunc(c1.cen.x), getmaxy – trunc(c1.cen.y), trunc(c1.raza));
circle(trunc(c2.cen.x), getmaxy – trunc(c2.cen.y),trunc(c2.raza));
circle(trunc(c3.cen.x), getmaxy – trunc(c3.cen.y),trunc(c3.raza));
setcolor(green);
draw(d1);
draw(d2);
setcolor(red);
circle(trunc(ccirc.cen.x), getmaxy –
trunc(ccirc.cen.y),trunc(ccirc.raza));
{inchiderea sistemului grafic,revenire…}
closegraph;
end.
FIŞIERE ÎN PASCAL
Declararea fişierelor.
În limbajul Pascal un fişier apare ca o secvenţă de componente de acelaşi tip
denumit tip de bază. Tipul de bază poate fi orice tip, în afară de tipul fişier. Fiecare
fişier folosit în program este reprezentat de o variabilă de tip fişier. Numai o
singură componentă a unui fişier este accesibilă într-un program, la un moment
dat. În limbajul Pascal există un tip special de fişiere: tipul text. Articolele unui
fişier de tip text sunt caractere structurate pe linii, fiecare linie fiind terminată cu
126
caractere CR, LF. Lungimea liniilor într-un fişier text este variabilă; de aceea
acest tip de fişiere nu poate fi prelucrat decât secvenţial.
Exemple de declaraţii de fişiere:
1) type
inreg=record
denumire : array[1..8] of char;
pret : real;
cant : integer;
end;
tfişier = file of inreg;
var
f1, f2 : tfişier;
2) file1, file2:text;
127
- V1, V2 … sunt variabile de tip string, char sau de tip numeric în care se
vor depune datele citite.
Exemplu următor ilustrează scrierea într-un fişier cu tip:
type
inf = record
nume: string(9);
preţ:integer;
end;
fls = file of inf;
var
f1:fis;
v1:inf;
begin
assign(f1,’fişier1’);
rewrite(f1);
v1.nume:’material1’;
v1. pret:1432;
write(f1,v1);
v1.nume:=’material2’;
v1.pret:=1300;
write(f1,v1);
…………
Accesul direct
Poziţionarea pe un anumit articol al unui fişier cu tip se face cu procedura:
Procedure SEEK(var F; N:longint);
Unde: - F este o variabilă de tip fişier
- N este nr. articolului pe care se doreşte poziţionarea.
Determinarea numărului de ordine al articolului curent se face cu funcţia
filepos (numai pentru fişiere cu tip):
function FILEPOS (var f):longint;
Determinarea numărului de articole ale unui fişier se face cu funcţia
filesize(numai pentru fişiere cu tip)
function Filesize(file F):longint;
Determinarea sfârşitului de fişier se realizează cu funcţia:
Function EOF(var f):boolean;
Funcţii specifice fişierelor text.
Pentru fişierele text se pot folosi următoarele funcţii:
function EOLN[(var f:text)]:boolean care returnează valoarea
true dacă poziţia curentă în fişier este în dreptul ultimului caracter (CTRL/Z).
function SEEKEOLN(var f:text):boolean care fixează
poziţia curentă în fişier pe primul caracter diferit de spaţiu sau TAB şi testează
caracterul pe care s-a poziţionat. Dacă acest caracter este Eoln (CR+LF) funcţia va
returna valoarea logică True.
128
function SEEKEOF[(var f:text)]:boolean care fixează
poziţia curentă în fişier pe primul caracter diferit de spaţiu sau TAB şi testează
caracterul pe acre s-a poziţionat. Dacă acest caracter este EOF (CTRL/Z) funcţia
va returna valoarea logică True.
Închiderea fişierului.
Închiderea (logică şi fizică) a fişierelor se realizează cu procedura close:
Procedure CLOSE(var f);
Operaţii aplicabile fişierelor închise
În limbajul Turbo Pascal pot fi apelate multe din operaţiile specifice
limbajului de comandă MS-DOS. Aceasta se aplică fişierelor închise şi sunt
implementate prin următoarele proceduri:
Procedure ERASE(var f); Realizează ştergerea unui fişier
Procedure RENAME(var f; Numenou:String); Realizează redenumirea
unui fişier
Procedure GETDIR(D:Byte; var S:String); Determină directorul curent (de
pe unitatea specificată de variabila de tip Bzte D în variabila de tip String S)
Procedure CHOIR (s:string) Determină schimbarea directorului curent
Procedure MKDIR(S:String) Determină crearea unui director gol indicat
prin variabila S
Procedure RMDIR(s:string) Dtermină ştergerea unui director gol indicat
prin variabila S
129
este descrisă de tipul de date “adresa”. Varaibila de fişier “fis” corespunde
fişierului de ieşire ‘fis’. Variabila inf este de tip “articol”.
Tipurile de date folosite sunt deci:
Adresa = record
Strada : string(10);
Număr : integer;
End;
Articol = record
Nume : string(10);
Adr : adresa;
Tel : longint
Note : tip_note;
End;
Tipul “tip_note” este un tablou de 5 elemente întregi.
c)Descrierea algoritmului în Pseudocod
* asignează şi deschide fişierele
* cât timp * nu s-au terminat datele din fişierul de intrare execută
citeşte inf. Nume, inf.adr.strada, inf.adr.număr,
inf.tel, inf.note
scrie * inf în fişierul de ieşire ‘fis’
_()
* închide fişierele
* deschide fişierul ‘fis’
* cât timp * nu s-au terminat articolele din ‘fis’ execută
citeşte * inf din fişierul ‘fis’
scrie inf.nume, inf.adr.strada, inf.adr.număr,
inf.tel, inf.note
_()
stop
131
B)Pornind de la fişierul creeat la punctul A) să se creeze un alt fişier
care să cuprindă în plus pentru fiecare student media obţinută precum şi
un indicator boolean pentru promovabilitate (true = promovat, false =
nepromovat).
a)Descrierea algoritmului în limbaj natural:
În secţiunea de iniţializare se deschide pentru citire fişierul ‘fis’ creeat
anterior la punctul a) şi pentru crearea fişierului ‘fismedia’ care va conţine în plus
pentru fiecare student media şi indicatorul de promovabilitate. Se citeşte apoi
secvenţial (articol după articol) fişierul ‘fis’, se calculează media şi indicatorul de
promovabilitate şi se scrie un articol corespunzător în fişierul ‘fismedia’. La
întâlnirea sfârşitului de fişier eof(fis) se închid ambele fişiere; se deschide apoi
pentru citire fişierul ’fismedia’. Afişarea conţinutului fişierului ‘fismedia’ se face
cu o secvenţă asemănătoare afişării ‘fis’ de la punctul A).
b)Descrierea şi semnificaţia structurilor de date folosite.
Se folosesc în plus faţă de structurile de date prezentate la A):
- tipul de date “articol_media” care descrie un articol din fişierul ‘fismedia’
- variabila “infmedia” de tip ‘articolmedia’
c) Programul în limbajul Pascal:
Program creare B;
{programul creeaza un fisier fismedia care contine: nume student, adresa, media}
uses crt;
const
nr note: =6;
type
tpnote: = array[1..nrnote] of interger;
adresa: = record
strada: string[10];
numar: integer;
end;
articol: = record
nume: string[10];
adr: adresa;
tel: longint;
note: tpnote;
end;
articolmedia: = record
art: articol;
media: real;
prom: boolean;
end;
var
fis : file of articol;
fismedia : file of articolmedia;
132
inf : articol;
infmedia: articolmedia;
media : real;
i : integer;
BEGIN{main}
assign(fis, ‘fis’);
reset(fis); {se deschide fisierul din care citim};
assign(fismedia, ‘fmedia’);
rewrite(fismedia); {se deschide fis media pentru scriere}
while not eof (fis) do
begin {se afiseaza media}
read (fis, inf);
whith inf do
begin
media: =0.0;
for i: = 1 to nrnote do
media: =media + note[i];
media: = media / 6;
end;
infmedia.art: =inf;
infmedia.media: = media;
if media > 5 then
infmedia.prom: = true
else
infmedia.prom: = false;
write(fismedia, infmedia);
end;
close(fismedia);
reset(fismedia);
clrscr;
while not eof (fismedia) do
begin {se afiseaza studentii promovati si nepromovati}
read(fismedia,infmedia);
with infmedia.art do
begin
write(nume,adr.strada, ‘ ‘ , adr.numar, ‘ ‘ ,tel) ;
for i: =1 to nrnote do write(‘ ‘, note[i]);
if infmedia.prom then
write(‘ promovat’)
else
write(‘nepromovat’);
writeln(‘media=’,infmedia.media:6:3);
end;
end;
133
END.
c)Folosind fişierul creat la punctul B să se creeze alte două fişiere care
să cuprindă:
1)studenţii promovaţi în ordinea descrescătoare a mediilor
2)studenţii nepromovaţi în ordinea alfabetică.
a)Descrierea algoritmului în limbaj natural:
În secţiunea de iniţializare a datelor se deschide pentru intrare fişierul
‘fismedia’ creat la punctul B şi pentru creare fişierele ‘fism’ şi ‘fisa’ care vor
cuprinde studenţii promovaţi ordonaţi descrescător după medie, respectiv studenţii
nepromovaţi ordonaţi alfabetic. Se citeşte apoi fiecare articol din fişierul ‘fismedia’
şi se completează tablourile ‘tabm’ respectiv ‘taba’cu studenţii promovaţi,
respectiv nepromovaţi. Se ordonează aceste tablouri conform criteriilor indicate.
Cele 2 tablouri se scriu apoi în cele fişiere cerute: ‘fism’ şi ‘fisa’. În final se
afişează cele două fişiere.
b)Descrierea şi semnificaţia structurilor de date folosite:
Apar în plus ca structuri de date tablourile tabm, taba care conţin elemente
de tip ‘articolmedia’.
c)Programul în limbajul Pascal:
Program ordonare; {programul creeaza doua fisiere:
- un fisier fism care contine studentii ordonati in ordine descrescatoare a mediilor
- un fisier fisa care contine studentii ordonati alfabetic }
uses crt;
const nrnote = 6;
nmax = 50;
type
tpnote = array [1..nrnote] of integer;
adresa: = record
strada: string[10];
numar: integer;
end;
articol: = record
nume: string[10];
adr: adresa;
tel: longint;
note: tpnote;
end;
articolmedia: = record
art: articol;
media: real;
prom: boolean;
end;
var
fis : file of articol;
134
fismedia,fism,fisa : file of articolmedia;
inf : articol;
infmedia : articolmedia;
media : real;
i,j,k : integer;
tabm,taba :array [1..nmax] of articol media;
ind : boolean;
BEGIN{main}
assign(fism, ‘fism’); rewrite(fism);{se deschide fism pentru scriere}
assign(fisa, ‘fisa’); rewrite(fisa); {se deschide fisa pentru scriere}
assign(fismedia, ‘fmedia’);
reset(fis); {se deschide fisierul din care citim};
i: =0; j: =0;
while not eof (fismedia) do
begin
read (fismedia, infmedia);
if infmedia.prom then
begin
i: =i + 1;
tabm [i] : = infmedia;
end
else
begin
j: =j + 1;
tabm [j] : = infmedia;
end;
end;
close (fismedia);
repeat {se ordoneaza descrescator studentii in ordinea mediilor}
ind: =true;
for k: =1 to i-1 do
if tabm[k].media < tabm[k+1].media
then
begin
infmedia: =tabm[k];
tabm[i]: = tabm[k+1];
tabm[k+1]: =infmedia;
ind: =false;
end;
until ind;
repeat {se ordoneaza studentii in ordine alfabetica}
ind: =true;
for k: =1 to j-1 do
if taba[k].art.nume < taba[k+1].art.nume
135
then
begin
nfmedia: =taba[k];
taba[i]: = taba[k+1];
taba[k+1]: =infmedia;
ind: =false;
end;
until ind;
for k: =1 to i do
write(fism,tabm[k]);
{se scriu in fisier studenti ordonati dupa nume}
for k: =1 to j do
write(fisa,tabm[k]); {scriu in fis. fisa studenti ordonati
alfabetic}
reset(fism); reset(fisa);
clrscr;
writeln(‘Studentii promovati:’);
while not eof (fism) do
begin {se afiseaza promovatii}
read (fism,infmedia);
with infmedia.art do
begin
write(nume,adr.strada, ‘ ’,adr.numar, ‘ ‘ ,tel );
for i: =1 to nrnote do
write(‘ ‘ , note[i]);
write(‘promovat’);
write(‘media=’,infmedia.media:6:3);
writeln;
end;
end;
writeln(‘Studentii nepromovati:’);
while not eof (fisa) do
begin {se afiseaza promovatii}
read (fisa,infmedia);
with infmedia.art do
begin
write(nume,adr.strada, ‘ ’,adr.numar, ‘ ‘ ,tel );
for i: =1 to nrnote do
write(‘ ‘ , note[i]);
write(‘nepromovat’);
write(‘media=’,infmedia.media:6:3);
end;
writeln;
end;
136
END.
137
f1,f2,f3 : text;
car : char;
BEGIN{MAIN}
Writeln(‘dati numele primului
fisier sursa’);
Readln(nume1);
Writeln(‘dati numele celui de-
al doilea fisier sursa’);
Readln(nume2);
Writeln(‘dati numele fisierului
destinatie’);
Readln(nume3);
assign(f1,nume1);
assign(f2,nume2);
assign(f3,nume3);
rewrite(f3);reset(f1);
while not eof(f1) do
begin
while not eoln(f1) do
begin
read(f1,car);
write(f3,car);
end;
readln(f1);
writeln(f3);
end;
close(f1); reset(f2);
while not eof(f2) do
begin
while not eoln(f2) do
begin
read(f2,car);
write(f3,car);
end;
readln(f2);
writeln(f3);
end;
close(f2);
close(f3);
END.
138