FORUM
Pagina de start a forumului eggzit.3xforum.ro
Lista Forumurilor Pe Tematici
FORUM | Reguli | Inregistrare | Login

POZE FORUM

Nu sunteti logat.
Nou pe simpatie:
Ada_net pe Simpatie.ro
Femeie
25 ani
Bucuresti
cauta Barbat
25 - 47 ani
FORUM / Informatica / Subalgoritmi Moderat de alex_89_eu
Autor
Mesaj Pagini: 1
nicoletast89
Administrator

Inregistrat: acum 20 ani
Postari: 104
CAPITOLUL AL II-LEA.
SUBALGORITMI

    2.1  Conceptul de subalgoritm
    Orice problemă poate apare ca o subproblemă S a unei probleme mai complexe C. Algoritmul de rezolvare a problemei S devine în acest caz un subalgoritm pentru algoritmul de rezolvare a problemei C.
    Pentru a defini un subalgoritm vom folosi propoziţia standard
    SUBALGORITMUL nume (lpf) ESTE:
unde nume este numele subalgoritmului definit, iar lpf este lista parametrilor formali. Aceştia sunt formaţi din variabilele care marchează datele de intrare (cele presupuse cunoscute) şi variabilele care marchează datele de ieşire (rezultatele obţinute de subalgoritm).
    Această propoziţie este urmată de textul efectiv al subalgoritmului, text care precizează calculele necesare rezolvării subproblemei corespunzătoare. Descrierea se va încheia cu cuvântul SFSUBALGORITM sau SF-nume.
    Dăm ca exemplu un subalgoritm cu numele MAXIM, care găseşte maximul dintre componentele vectorului    X = (x1,x2, ..., xn).
    Datele cunoscute pentru acest subalgoritm sunt vectorul X şi numărul n al componentelor vectorului X. Ca rezultat vom obţine maximul cerut, pe care-l vom nota cu max. Deci lista parametrilor formali conţine trei variabile, n, X şi max. Subalgoritmul este dat în continuare.
    SUBALGORITMUL maxim(n,X,max) ESTE:
       FIE max:=x1;
       PENTRU i:=2;n EXECUTĂ
          DACĂ xi>max ATUNCI max:=xi SFDACĂ
    SFPENTRU
    SF-maxim
    ÃŽn cadrul multor algoritmi este necesar calculul valorilor unei funcţii în diferite puncte. Este necesar să definim funcţia printr-un subalgoritm de tip funcţie.
    Pentru definirea unui subalgoritm de tip funcţie se foloseşte un antet care precizează numele funcţiei şi variabilele de care depinde ea. Subalgoritmul are forma:
    FUNCŢIA nume(lpf) ESTE:    {Antetul funcţiei}
        text    {corpul funcţiei}
    SF-nume    {marca de sfârşit}
    ÃŽn corpul funcţiei trebuie să existe cel puţin o atribuire în care numele funcţiei apare în partea stângă, deci prin care funcţia primeşte o valoare.
    Dăm ca exemplu o funcţie numar : R --> {2,3,4,5}, definită matematic astfel:
    ÃŽn Pseudocod descrierea este următoarea:
    FUNCŢIA numar(x) ESTE:
       DACĂ  x<0.2 ATUNCI numar:=2 ALTFEL
          DACĂ  x<0.5 ATUNCI numar:=3 ALTFEL
             DACĂ  x<0.9 ATUNCI numar:=4
                              ALTFEL numar:=5
             SFDACĂ
          SFDACĂ
       SFDACĂ
    SF-numar

    Am văzut că definiţia unei funcţii constă dintr un antet şi dintr un bloc care va defini acţiunile prin care se calculează valoarea funcţiei. ÃŽn antet se precizează numele funcţiei şi lista parametrilor formali.
    ÃŽn concluzie, există două categorii de subalgoritmi: de tip funcţie şi subalgoritmi     propriu-zişi, cărora li se mai spune şi proceduri. Importanţa lor va fi subliniată prin toate exemplele care urmează în acest curs. ÃŽn încheiere menţionăm că subprogramele de tip funcţie se folosesc în scopul definirii funcţiilor, aşa cum sunt cunoscute ele din matematică, în timp ce subalgoritmii de tip procedură se referă la rezolvarea unor probleme ce apar ca subprobleme, fiind algoritmi de sine stătători.

    2.2  Apelul unui subalgoritm
    Am văzut că un subalgoritm este dedicat rezolvării unei subprobleme S a unei probleme mai complexe C. Algoritmul corespunzător problemei C va folosi toate operaţiile necesare rezolvării problemei S, deci va folosi ca parte întregul subalgoritm conceput pentru rezolvarea subproblemei S. Spunem că el va apela acest subalgoritm.
    ÃŽn Pseudocod apelul unei funcţii se face scriind într o expresie numele funcţiei urmat de lista parametrilor actuali. Trebuie să existe o corespondenţă biunivocă între parametrii actuali şi 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 şi parametrul actual corespunzător trebuie să se refere la aceeaşi entitate, trebuie să aibă aceeaşi semnificaţie, să reprezinte aceeaşi structură de date. Putem considera că în timpul execuţiei algoritmului cei doi parametri devin identici.
    Folosirea unui subalgoritm în cadrul unui algoritm se face apelând acest subalgoritm prin propoziţia standard        CHEAMĂ  nume (lpa);
unde nume este numele subalgoritmului apelat iar lpa este lista parametrilor actuali. Această listă conţine toate datele de intrare (cele cunoscute în subproblema corespunzătoare) şi toate rezultatele obţinute în subalgoritm. Şi în acest caz între lista parametrilor formali din definiţia subalgoritmului şi lista parametrilor actuali din propoziţia de apel trebuie să existe o corespondenţă biunivocă, ca şi în cazul funcţiilor. Ca o primă verificare a respectării acestei corespondenţe, subliniem că numărul parametrilor actuali trebuie să coincidă cu numărul parametrilor formali.
    Ca exemplu de apelare a funcţiilor, dăm în continuare un program pentru a calcula a câta zi din anul curent este ziua curentă (zi,luna,an). El foloseşte un subprogram de tip funcţie pentru a obţine numărul zilelor lunii cu numărul de ordine i şi un altul pentru a verifica dacă un an este bisect sau nu. Aceste două funcţii sunt:
- NRZILE(i) furnizează numărul zilelor existente în luna i a unui an nebisect;
- BISECT(an) adevărată dacă anul dintre paranteze este bisect.
Algoritmul este următorul:
ALGORITMUL NUMĂRĂZILE ESTE:
  CITEŞTE zi, luna, an;
  FIE nr:=zi;
  DACĂ luna>1 ATUNCI
    PENTRU i:=1, Luna-1 EXECUTĂ nr:=nr+NRZILE(i) SFPENTRU
  SFDACĂ
  DACĂ luna>2 ATUNCI
    DACĂ  BISECT(an) ATUNCI nr:=nr+1 SFDACĂ
  SFDACĂ
  TIPĂREŞTE  nr;
SFALGORITM

    Să observăm că în proiectarea acestui algoritm nu este necesar să cunoaştem textul subalgoritmilor folosiţi, ci doar specificarea acestor subalgoritmi, numele lor şi lista parametrilor formali. La acest nivel accentul trebuie să cadă pe proiectarea algoritmului care apelează, urmând să se revină ulterior la proiectarea subalgoritmilor apelaţi, conform specificaţiei acestora. ÃŽn cazul de faţă este necesară  descrierea funcţiilor NRZILE(i) şi BISECT(an). Lăsăm această descriere ca temă pentru cititor.
    Ca exemplu de apelare a unei proceduri vom scrie mai jos o procedură care efectuează suma a două polinoame.
Un polinom P(X) este dat prin gradul său, m, şi prin vectorul coeficienţilor P = (p0, p1, ..., pm) (prin pi s-a notat coeficientul lui Xi).
    Procedura SUMAPOL(m,P,n,Q,r,S) trebuie să efectueze suma    S(X) = P(X)+Q(X),
unde P este un polinom de gradul m, iar Q este un polinom de gradul n, date. Suma lor, S, va fi un polinom de gradul r calculat în subalgoritm. Pentru efectuarea ei este utilă o altă procedură care adună la suma S(X) un alt polinom, T(X), de grad mai mic sau egal decât gradul polinomului S(X). O astfel de procedură se dă în continuare.
    SUBALGORITMUL SUMAPOL1(n,T,r,S) ESTE:    {n  r}
    {S(X):=S(X)+T(X)}
       PENTRU i:=0;n EXECUTĂ
           si := si+ti
       SFPENTRU
    SF-SUMAPOL1
    Subalgoritmul SUMAPOL apelează acest subalgoritm, aşa cum se poate vedea în continuare.
   SUBALGORITMUL SUMAPOL(m,P,n,Q,r,S) ESTE:    {S(X):=P(X)+Q(X)}
    DACĂ m<n
        ATUNCI r:=n;  S:=Q;
                    CHEAMĂ SUMAPOL1(m,P,r,S)
        ALTFEL r:=m;  S:=P;
                    CHEAMĂ SUMAPOL1(n,Q,r,S)
    SFDACĂ
   SF-SUMAPOL
    Să observăm că în textul acestui subalgoritm am extins semnificaţia propoziţiei de atribuire, permiţând atribuirea S:=Q. Acest lucru este normal întrucât S notează un polinom, iar Q este un polinom cunoscut; prin atribuire S primeşte o valoare iniţială, cea dată de polinomul Q.
    Subliniem că atribuirea      v := u
va fi corectă în cazul în care variabilele u şi v reprezintă aceleaşi obiecte matematice, deci au aceeaşi semnificaţie.

    2.3  Alte exemple
    Ca un al doilea exemplu de definire şi folosire a subalgoritmilor, să considerăm următoarea problemă:
    Se dau trei mulţimi de numere:
   A  =  { a1, a2, ... , am }
   B  =  { b1, b2, ... , bn }
   C  =  { c1, c2, ... , cp }
    Se cere să se tipărească în ordine crescătoare elementele fiecărei mulţimi, precum şi a mulţimilor A U B, B U C, C U A.
    ÃŽn rezolvarea acestei probleme se întâlnesc următoarele subprobleme:
S1: Să se citească elementele unei mulţimi;
S2: Să se efectueze reuniunea a două mulţimi;
S3: Să se tipărească elementele unei mulţimi;
S4: Să se ordoneze crescător elementele unei mulţimi.
    Presupunând că pentru rezolvarea acestor subprobleme am conceput subalgoritmii:
     CITMUL(m,A);
     REUNIUNE(m,A,n,B,k,R);
     TIPMUL(m,A);
     ORDON(m,A);
care sunt specificaţi mai jos (la locul definirii lor) prin comentarii, algoritmul de rezolvare a problemei de mai sus este dat în continuare. ÃŽntrucât operaţiile respective se folosesc de mai multe ori (de 3 ori), am definit un subalgoritm TIPORDON(m,A) care ordonează mai întâi elementele mulţimii A şi apoi le tipăreşte. 
    ALGORITMUL OPER MULTIMI ESTE:    { A6: Subalgoritmi }
    CHEAMĂ CITMUL(m,A);
    CHEAMĂ CITMUL(n,B);
    CHEAMĂ CITMUL(p,C);
    CHEAMĂ TIPORDON(m,A);
    CHEAMĂ TIPORDON(n,B);
    CHEAMĂ TIPORDON(p,C);
    CHEAMĂ REUNIUNE(m,A,n,B,k,R);
    CHEAMĂ TIPORDON(k,R);
    CHEAMĂ REUNIUNE(n,B,p,C,k,R);
    CHEAMĂ TIPORDON(k,R);
    CHEAMĂ REUNIUNE(p,C,m,A,k,R);
    CHEAMĂ TIPORDON(k,R);
    SFALGORITM
 
    Subalgoritmii apelaţi mai sus sunt definiţi în continuare.

SUBALGORITMUL CITMUL(n,M) ESTE:    {Citeşte n şi M}
CITEŞTE n;    {n=nr. elementelor mulţimii}
CITEŞTE (mi,i=1,n);    {M=mulţimea cu elementele m1,m2,...,mn}
SF CITMUL

SUBALGORITMUL ORDON(n,M) ESTE:    {Ordonează crescător cele n}
REPETĂ    {elemente ale mulţimii M}
   FIE ind:=0;    {Cazul M este ordonată}
   PENTRU i:=1;n 1 EXECUTĂ
     DACĂ mi>mi+1 ATUNCI    {schimbă ordinea celor}
       FIE t := mi;    {două elemente}
           mi:=mi+1;  mi+1:=t;
           ind:=1;    {Cazul M nu era ordonată}
     SFDACĂ
   SFPENTRU
PÂNĂCÂND ind=0 SFREP
SF-ORDON
SUBALGORITMUL REUNIUNE(m,A,n,B,k,R) ESTE:    {  R := A U B  }
    { k = numărul elementelor mulţimii R }
FIE k:=m;  R := A;
PENTRU j:=1,n EXECUTĂ
   FIE ind:=0;    {Ipoteza bj nu e in A}
   PENTRU i:=1;m EXECUTĂ
     DACĂ bj=ai ATUNCI ind:=1 {bj este in A}  SFDACĂ
   SFPENTRU
   DACĂ ind=0 ATUNCI k:=k+1; rk:=bj SFDACĂ
SFPENTRU
SF REUNIUNE
SUBALGORITMUL TIPMUL(n,M) ESTE:    { Tipăreşte cele n elemente }
PENTRU i:=1;n EXECUTĂ    { ale mulţimii M }
   TIPĂREŞTE mi
SFPENTRU
SF TIPMUL

SUBALGORITMUL TIPORDON(n,M) ESTE:    { Ordonează şi tipăreşte }
CHEAMĂ ORDON(n,M);    { elementele mulţimii M }
CHEAMĂ TIPMUL(n,M);
SF TIPORDON
    Tot ca exemplu de folosire a subalgoritmilor, vom scrie un algoritm pentru rezolvarea următoarei probleme:
dirigintele unei clase de elevi doreşte să obţină un clasament al elevilor în funcţie de media generală. ÃŽn plus, pentru fiecare disciplină în parte doreşte lista primilor şase elevi.
    ÃŽn rezolvarea acestei probleme este necesară găsirea ordinii în care trebuiesc tipăriţi elevii în funcţie de un anumit  rezultat: nota la disciplina "j", sau media generală. Am identificat prin urmare două subprobleme independente, referitoare la:
  (1) aflarea ordinii în care trebuie tipărite n numere pentru a le obţine ordonate;
  (2) tipărirea elevilor clasei într o anumită ordine.
    Prima subproblemă se poate specifica astfel:
Dându se numerele x1, x2, ...  , xn, găsiţi ordinea o1, o2, ..., on, în care aceste numere devin ordonate descrescător, adică
                x[o1]  x[o2]  ... x[on] .
    Pentru rezolvarea ei vom da un subalgoritm ORDINE în care intervin trei parametri formali:
     n, numărul valorilor existente;
     X, vectorul acestor valori;
     O, vectorul indicilor care dau ordinea dorită.
    Primii doi parametri marchează datele presupuse cunoscute, iar al treilea, rezultatele calculate de subalgoritm.
SUBALGORITMUL ORDINE(n,X,O) ESTE:
    {n, numărul valorilor existente}
    {X, vectorul acestor valori}
    {O, vectorul indicilor care dau ordinea dorită}
PENTRU i:=1; n EXECUTĂ oi :=i SFPENTRU
REPETĂ ind:=0;
     PENTRU i:=1;n 1 EXECUTĂ
        DACĂ x[oi] < x[oi+1] ATUNCI
           FIE ind:=1;   t:=oi+1 ;
               oi+1 :=oi; oi :=t;
        SFDACĂ
     SFPENTRU
PANÂCÂND ind=0 SFREP
SF ORDINE
    A doua subproblemă se poate specifica astfel:
    Dându se ordinea o1,o2, ..., on, a elevilor clasei, numele şi mediile acestora, să se tipărească numele şi mediile primilor k elevi în ordinea specificată.
    Subalgoritmul TIPAR, dat în continuare,  rezolvă această problemă.
SUBALGORITMUL TIPAR(k, NUME, O) ESTE:
PENTRU i:=1;k EXECUTĂ
   Tipăreşte datele elevului de rang oi.
SFPENTRU
SF TIPAR
    Variabilele folosite pentru problema dată sunt următoarele: 
     n reprezintă numărul elevilor clasei;
     m este numărul disciplinelor la care elevii primesc note;
     NUME este vectorul care reţine numele elevilor: NUMEi este numele elevului cu           numărul de ordine i;
     NOTE este matricea notelor elevilor, având n linii şi m coloane; 
    NOTEi,j este nota elevului cu numele NUMEi la disciplina cu numărul de ordine j;
    NOTE.j este coloana a j a a matricei NOTE şi reprezintă notele elevilor la disciplina       j;
     MEDII este vectorul mediilor generale.
       Algoritmul se dă în continuare:
ALGORITMUL CLASAMENT ESTE:    { Algoritmul 7: Ordonare }
CITEŞTE m,    {numărul disciplinelor şi}
        n,    {al elevilor}
        NUMEi, i=1,n,    {numele elevilor}
        NOTEi,j, j=1,m, i=1,n;    {notele elevilor}
PENTRU i:=1;n EXECUTĂ    { calculează media generală}
   FIE  S:=0;    {a elevului i}
   PENTRU j:=1;m EXECUTĂ  S:=S+NOTEi,j SFPENTRU
   FIE MEDIIi:=S/m
SFPENTRU
CHEAMĂ ORDINE(n,MEDII,O);
CHEAMĂ TIPAR(n,NUME,O) 
PENTRU j:=1;m EXECUTĂ
   CHEAMĂ ORDINE(n,NOTE.j,O);
   CHEAMĂ TIPAR(6,NUME,O);
SFPENTRU
SF ALGORITM
2.4    Apel recursiv
    ÃŽn exemplele date se observă că apelul unui subprogram se face după ce el a fost definit. Este însă 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.
    Ca exemplu, definim în continuare o funcţie care calculează recursiv valoarea n!. Se va folosi formula n! = n.(n 1)! în cazul n>0 şi faptul că 0!=1. Recursivitatea constă în faptul că în definiţia funcţiei Factorial de n se foloseşte aceeaşi funcţie Factorial dar de argument n-1. Deci funcţia Factorial se apelează pe ea însăşi. Este important ca numărul apelurilor să fie finit, deci ca procedeul de calcul descris să se termine.
FUNCTIA Factorial(n) ESTE:
   DACĂ n=0    ATUNCI Factorial:=1
        ALTFEL Factorial:= n*Factorial(n 1)
   SFDACĂ
SF-Factorial;
    Tot ca exemplu de apel recursiv putem descrie o funcţie ce calculează maximul a n numere x1,x2,...,xn . Ea se bazează pe funcţia MAXIM2 care calculează maximul a două numere, descrisă în continuare.
    FUNCŢIA MAXIM2(a,b) ESTE:
       DACĂ a<b    ATUNCI MAXIM2:=b
            ALTFEL MAXIM2:=a
       SFDACĂ
    SF-MAXIM2
Funcţia MAXIM, care calculează maximul celor n numere este următoarea:
    FUNCŢIA MAXIM(n,X)    {Calculează maximul a n numere}
                      ESTE:    {X=vectorul cu numerele date}
       DACĂ n=1
            ATUNCI MAXIM:=x1
            ALTFEL MAXIM:=MAXIM2( MAXIM(n-1,X), xn)
       SFDACĂ
    SF-MAXIM


pus acum 20 ani
   
Pagini: 1  

Mergi la