Você está na página 1de 8

Algoritmo Programao II

2011/2012
Beatriz Carmo DI-FCUL Engenharia Geogrfica Estatstica Aplicada Outros
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 1

Um algoritmo um conjunto bem definido de aces procurando resolver um problema Os algoritmos so construdos custa de trs conceitos bsicos:
Sequncia Seleco (condio) Repetio (iterao)

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

As estruturas de controlo
A sequncia
Inicializao

As estruturas de controlo
A repetio (iterao)

int i = 4; int j = 8; int soma = i + j; If (i>=0) j = i; else j = -i;

A seleco (condio)

Corpo do ciclo

soma = 0; numero=1; while (numero<=4) { soma = soma + numero; numero++; }

Guarda do ciclo: Expresso lgica que determina a execuo ou no da prxima iterao

soma = 0; for (numero=1; numero<=4; numero++){ soma = soma + numero; }


3 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 4

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

Ciclo while
{PRE} Inicializao I0 while (guarda G) { {G} passo P }
Eventual pr-condio

Processamento iterativo
Outro exemplo de iterao factorial /*pr-condio: n>=0 */ int fact (int n) { int produto = 1, i = n; while (i>=1) { produto *= i; i--; } return produto; }
5 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 6

n! = n (n-1)! 0!=1

Corpo do ciclo

{G} Ps-condio que se quer garantir {POS} Num ciclo, em cada iterao (passo) h uma aproximao da soluo final.
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso

Processamento Recursivo
Processamento iterativo
implementado de forma repetitiva comeando de um valor conhecido processamento de baixo para cima Funes em C podem invocar-se entre si.
(A. Adrego)

Existe a capacidade de uma funo se invocar a si mesma recurso ou recorrncia. Na linguagem de programao C, optamos, para cada problema, entre iterao e recurso.

Processamento recursivo
parte de um valor desconhecido e adia o clculo at ser atingido um valor conhecido processamento de cima para baixo
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 7

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

Recurso
Para usar a recurso preciso partir o problema P em duas partes: a base da recurso e o passo da recurso. A base da recurso corresponde aos casos triviais onde de imediato obtemos a resposta. O passo a simplificao do problema, fazendo com que o problema principal seja resultado de subproblemas mais simples (que necessrio calcular) - dividir para conquistar
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 9

Recurso
Exemplo: factorial n! = n * (n-1) * * 1 pode ser escrito recursivamente: 0! = 1 base n! = n * (n-1)! passo
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 10

Recurso
Resoluo Recursiva
24

Grfico de chamadas recursivas fact(4) return 4*fact(3)


6

/*pr-condio: n>=0 */

int fact (int n) { if (n == 0) return 1; caso base return n * fact (n-1); passo }
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 11 bc@di.fc.ul.pt

return 3*fact(2)
2

return 2*fact(1)
1

return 1*fact(0)
1

return 1
12

GU-ProgII-OL-2011/2012-2 recurso

Recurso
Quando se implementa um algoritmo de forma recursiva, temos que assegurar que: existe uma instruo que
pra a invocao recursiva e calcula efectivamente um valor

Problemas a ter em ateno


Recurso Infinita: sem casos base adequados, a recurso pode nunca terminar Os subproblemas tm de convergir para os casos base contra-exemplo fact(n) = fact(n+1) / (n+1)
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 14

o valor das sucessivas invocaes alterado de maneira a atingir a condio de paragem


bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 13

Sequncia de Fibonacci
Outro exemplo de recurso: fib(0) = 0 fib(1) = 1 fib(n) = fib(n-1) + fib(n-2), n2

rvore de recurso
A rvore de recurso uma estrutura onde se apresentam todas as invocaes recursivas de uma funo
fib(4) fib(2) fib(0) fib(1) fib(3) fib(1) fib(2) fact(1) fib(0) fib(1) fact(0) fact(4) fact(3) fact(2)

Soluo Recursiva int fib (int n) { if (n==0) return 0; if (n==1) return 1; return fib(n-1) + fib(n-2); }

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

15

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

16

Recurso: linear vs no-linear


Quando na funo existe apenas uma invocao a si prpria (como no caso do factorial), diz-se que a recurso linear. Quando a funo se invoca duas ou mais vezes (como na sequncia de Fibonacci), trata-se de uma recurso no-linear.
A resoluo do problema pode ser ineficiente
bc@di.fc.ul.pt

Soluo Iterativa int fib_iter(int n) { int a=0, b, i, temp; b = n==0 ? 0 : 1; for(i=2; i<=n; i++) { temp = b; b += a; a = temp; } return b; }

Soluo Recursiva Linear int fib_rec_linear(int n) { if (n==0) return 0; if (n==1) return 1; return fib_aux(n,0,1); } int fib_aux(int n, int a, int b) { if (n==1) return b; return fib_aux(n-1,b,a+b); }
GU-ProgII-OL-2011/2012-2 recurso 18

Tentar arranjar uma soluo iterativa ou arranjar uma recurso linear


17

GU-ProgII-OL-2011/2012-2 recurso

bc@di.fc.ul.pt

Iterao vs Recurso
A recurso til quando no existe uma soluo iterativa bvia. A soluo recursiva tende a ser mais fcil de interpretar e codificar. Apesar de potencialmente mais lenta, verificar a sua correco mais acessvel.

Iterao vs Recurso
A soluo recursiva tende a ser menos eficiente que a soluo iterativa.
A recurso precisa de mais recursos pois as mltiplas invocaes tm de ser armazenadas e geridas em memria (o que tem um custo associado). Existe uma pilha de invocaes, ie, uma estrutura de dados que mantm quais as funes que esto espera de resposta, os valores das respectivas variveis locais, e onde cada uma deve continuar a executar quando recomear.
19 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 20

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

Iterao vs Recurso
Entre os problemas que tm uma soluo recursiva bvia h que distinguir os seguintes casos: Os que tm uma soluo iterativa simples, como o clculo do factorial.
Neste caso a soluo recursiva no deve ser escolhida.

Iterao vs Recurso
Aqueles em que a complexidade da soluo iterativa consideravelmente maior, no compensando o eventual ganho de desempenho (como o algoritmo de ordenao
quicksort que tambm veremos)

Aqueles que a soluo iterativa no sendo trivial, os dois tipos de implementao so igualmente vlidos (como a procura binria que
veremos)
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 21 bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 22

Memorizao
Outra forma de acelerar recurses no-lineares o uso de memorizao, ou seja, ir guardando as solues calculadas para no ter de as repetir. Esta a tcnica usada na programao dinmica para optimizar problemas com solues recursivas onde os subproblemas possuem clculos comuns
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 23

#include <stdlib.h> /* declares malloc() */ int fibonacciDinamico (int n ) { int i; int* sols= malloc ((n+1)*sizeof(int)); sols[0]=0; sols[1]=1; for (i=2; i<=n; i++) sols[i]= sols[i-1] + sols[i-2]; return sols[n]; } Comparar com as solues anteriores
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 24

Recurso Terminal
Se uma funo tem
uma nica invocao recursiva que feita na ltima instruo executada, int f (int n) {

Recurso Terminal
Soluo recursiva Soluo iterativa int f(int n) { int temp = 1; while (n>0) {
/* o passo*/

ento diz-se que tem uma recurso terminal.

/*a base da recurso */ if (n<=0) return 1; /* o passo*/ return n * f(n/2); } }


25 bc@di.fc.ul.pt

Este tipo de funo pode ser traduzido, mais ou menos facilmente, por uma funo iterativa
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso

temp = temp * n; n = n / 2; } return temp;


GU-ProgII-OL-2011/2012-2 recurso 26

Torre de Hani

Torres de Hani
Invocao: hanoi (0, 2, discs);

Torre origem Torre destino N de discos

Temos 3 colunas e N discos Inicialmente os N discos, que formam uma torre, esto numa coluna Em cada turno desloca-se um disco do topo de uma coluna para outra coluna sem o colocar sobre um disco menor O objectivo mover uma torre de uma coluna para outra
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 27 bc@di.fc.ul.pt

hanoi (source, temp, discs-1); hanoi (source, target, 1); hanoi (temp, target, discs-1);

GU-ProgII-OL-2011/2012-2 recurso

28

hanoi (0, 2, 3);

/*Torre origem=0 Torre destino=2 N de discos=3 */

Torre de Hani
void hanoi (int source, int target, int discs) { int temp; if (discs == 1) {
/* imprime movimentos realizados */

hanoi (source, temp, discs-1);

hanoi (source, target, 1);

hanoi (temp, target, discs-1);

printf ("%d -> %d\n", source, target); } else{ temp = 3 - source - target; hanoi (source, temp, discs-1); hanoi (source, target, 1); hanoi (temp, target, discs-1); } }
bc@di.fc.ul.pt GU-ProgII-OL-2011/2012-2 recurso 30

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

29

Bibliografia
Estruturas de Dados e Algoritmos em C Antnio Adrego da Rocha, FCA, 2008 Programao II, Notas Tericas, Prof. Joo Neto, LTIC 09/10 Slides de Programao II 08/09, Prof. Carlos Loureno Programao, Algoritmos e Estruturas de Dados, 2 edio, Joo Neto, Escolar Editora, 2008 The C book. Verso online da segunda edio livro de Mike Banahan, Declan Brady e Mark Doran, publicado pela Addison Wesley, 1991. http://publications.gbdirect.co.uk/c_book/

bc@di.fc.ul.pt

GU-ProgII-OL-2011/2012-2 recurso

31

Você também pode gostar