Você está na página 1de 8

 

1. Funes Recursivas
Qualquer funo em linguagem C/C++ pode ser chamada de um modo recursivo, isto , uma funo pode chamar-se a si prpria. O nmero de vezes que uma funo pode ser chamada recursivamente limitado ao tamanho da pilha (stack), se este valor for alcanado, o programa termina com error: Stack Fault ou Stack Overflow.

Definio: Funo Recursiva uma funo que invoca a si prpria, ou invoca outra funo, e na sequncia das diversas subfunes, uma das subfunes invoca a primeira funo.

Cada vez que uma funo chamada de forma recursiva, alojado e guardado uma cpia dos seus parmetros por forma a no perder os valores dos parmetros das chamadas anteriores. Em cada instncia da funo, s so directamente acessveis os par etros

criados para esta instncia, no sendo directamente acessveis os parmetros de outras instncias.

A informao guardada na invocao de uma funo designada por Estrutura de Invocao e consiste basicamente na seguinte informao:

E E E E

Endereo de retorno (quando a funo terminar o programa deve continuar a sua execuo na linha seguinte invocao da funo) Estado dos registos e flags do CPU Variveis passadas como argumentos para a funo (por valor, referncia, etc.) Varivel de retorno (por valor, referncia, etc.)

A invocao de uma funo recursiva igual invocao de uma funo no recursiva, na qual necessrio guardar uma estrutura de invocao, sendo esta estrutura libertada depois do fim da execuo da funo e afectao/actualizao do valor de retorno.

 "!$#%&#' !()102(#$345&62)7

0&8#9@!BACDA

FGHIPQR SRTUTG

Caractersticas das funes recursivas: As funes recursivas contm duas partes fundamentais: 1. Ponto de Paragem: o ponto de paragem da recursividade resolvido sem utilizao de recursividade, sendo este ponto geralmente um lim ite superior ou inferior da regra geral. 2. Regra Geral: o mtodo geral da recursividade reduz a resoluo do problem atravs da invocao recursiva de casos mais pequenos, sendo estes casos mais pequenos resolvidos atravs da resoluo de casos ainda mais p equenos, e ass sucessivamente, at atingir o ponto de paragem que finaliza o mtodo. (n == 0) 1 Factorial (n) = (n) n * (n 1)!
Ponto de Paragem Regra Geral

Exemplo:

Nota: As variveis declaradas como estticas, no requerem novo armazenamento, em cada invocao da funo recursiva. Estas variveis existem durante todo o programa, no sendo criado cpias destas variveis na invocao de uma funo de modo recursivo.

Desenho de algoritmos recursivos:


1. 2. 3. 4. 5.

Obter uma soluo de como o problema pode ser dividido em passos menores Definir um ponto de parage Definir uma regra geral Verificar se o algoritmo termina Desenhar uma rvore de execuo do programa, mostrando o desenvolvimento do processo.

Utilizar recursividade ou no ?

Na fase de concepo, os mtodos recursivos so um bom processo flexvel de pensamento

Na fase de imp ementao, necessrio avaliar os diversos mtodos e questionar qual o melhor mtodo para as circunstncias especificas (mais eficaz e eficiente).

V R"W$X%IU&X'G W(Q)TG1YP`(XP$Ua4Ub&c`)d

Y&eX9R@WUgfhTGif

pqrstuv wvxyxq

Concluso: A recursividade deve ser utilizada quando a forma recursiva a forma mais simples e intuitiva de implementar uma soluo para a resoluo do problema.

Exemplo n. 1
Escrever uma sequncia de nmeros na vertical
#include <iostream.h> void esc_numero1(int num) { if (num > 0) { esc_numero1(num-1); cout << num << " "; } } void esc_numero2(int num) { if (num > 0) { cout << num << " "; esc_numero2(num-1); } } int main() { int numero=0; cout << "Introduza o numero inicial (>0)"; cin >> numero; esc_numero1(numero); cout << endl; esc_numero2(numero); }

v"$%sy&'q (u)xq1t(t$y4y&)

&9v@yghxqi

 d

Exemplo n. 2
Funo Factorial Mtodo Recursivo
long int factorial1( int num ) { if (num < 0) { // Se o nmero menor que zero ento retornar erro. retun(-1); } if ( (num == 0) || (num == 1) ) { // Se o numero igual a 0 ou 1, ento o seu factorial 1. return(1); } else { // Caso contrrio, invocar recursivamente a funo. return( num * factorial1( num - 1 ) ); } }

Mtodo Iterativo
long int factorial2( int num ) { long int resultado = 1; if (num < 0) { // Se o nmero menor que zero ento retornar erro. retun(-1); } for(int i = 2; i <= num; i++) { resultado *= i; } return(resultado); } void main() { int numero=0; long int fact=0; cin >> numero; fact = factorial1(numero); cout << endl << numero << != << fact << endl; fact = factorial2(numero); cout << endl << numero << != << fact << endl; }

Nota: A funo factorial retorna o mesmo valor em ambas as implementaes, contudo, a forma sem recursividade ligeiramente mais eficiente.

e "f$g%d&g' f()1hi(g$dj4dk&li)m

h&ng9@fdpoqro

stuvwxy zy{|{t

Exemplo n. 3
Inverso de uma string Mtodo Recursivo
void stringinv_aux (char * s, int i, int j) { if ( j - i > 2) { stringinv_aux (s, i + 1, j 1); // Inverter a sub-string. } // Trocar os caracteres extreinos. char aux = s[j]; s[j] = s[i]; s[i] = aux; } void stringinv(char * str) { stringinv_aux(str, 0, strlen(str)); } exemplo: Inverter a string bonitos instncia i j string entrada da funo string sada da funo 1 0 6 bonitos sonit 2 1 5 sonit sonit 3 2 4 sonit sotinob

Mtodo Iterativo
void stringinv_aux(char * str, int i, int j) { for( int i = O ; i < j ; ++i, --j ) { // Trocar os caracteres extremos. char aux = s[j]; s[j] = s[i]; s[i] = aux; } } void stringinv(char * str) { stringinv_aux(str, 0, strlen(str)); }

} y"~$%v|&'t ~(x){t1w(w$|4|&)

&9y@~|gh{ti

 

Exemplo n. 4
Converter nmeros inteiros em strings Mtodo Recursivo
void itoa_aux(int num, char * &s) { if ( num == 0 ) return ; itoa_aux( int(num / 10), s); *s++ = n % 10 + '0'; } void itoa(int num, char *s) { if (num < 0) // Se o valor for negativo. { *s++ = -; n = -n; } itoa_aux( num , s ); *s = 0; // Terminar a String )

Mtodo Iterativo
void itoa(int num, char * s) { int valor, i = 0, j; char c; if ( (valur = num) < 0) { num = -num; } do { s[i++]= n %10 + 0; } while(( num /= 10) > O ); if ( valor < 0) { s[i++] = -; } s[i] = \0; // Inverter a string for ( j = 0, --i; i > j ; --i, ++j) { c = s[i]; s[i] =s[j]; s[j] = c; } }

"$%&' ()1($4&)

&9@Dg

 

Exemplo n. 5
Clculo do resto da diviso de dois nmeros Considere a seguinte funo que calcula o resto da diviso de dois nmeros, atravs da sucessiva subtraco ao 1 nmero do valor do 2 nmero.

Mtodo Recursivo
#include <iostream> int res(int numerador, int denominador); int res(int x, int y) { if (x < y) return(x); return( res(x y, y) ); }

Mtodo Iterativo
#include <iostream> int res(int numerador, int denominador); int res(int x, int y) { while(x >= y) { x = x y; } return( x ); }

"$%&' ()1($4&)

&9@Dg

 

Exemplo n. 6
Clculo do resto da diviso de dois nmeros Considere a seguinte funo que calcula a multiplicao de dois nmeros positivos, maiores qu zero, atravs de sucessivas somas do primeiro nmero.

Mtodo Recursivo
#include <iostream> long int mult(int x, int y); long int mult(int x, int y) { if (y == 1) return(x); else return(x + mult(x, y-1)); }

Mtodo Iterativo
#include <iostream> long int mult(int x, int y); long int mult(int x, int y) { long int res=0; while( y != 1) { res += x; y--; } return(res); }

Exemplo n. 7
Clculo da seguinte formula:

Mtodo Recursivo

n i =1

(i * i )

#include <iostream> long int sumatorio(int num); long int sumatorio (int num) { if (num == 0) return(0L); else return( num * num + sumatorio( num 1 ); }

"$%&' ()1($4&)

&9@ghi

Você também pode gostar