Escolar Documentos
Profissional Documentos
Cultura Documentos
Recursividade Na Programação
Recursividade Na Programação
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
Variveis passadas como argumentos para a funo (por valor, referncia, etc.)
Varivel de retorno (por valor, referncia, etc.)
!"#$%
&'(
*)+,)
./012
34 54676/
Exemplo:
(n == 0) 1
Factorial (n) =
(n) n * (n 1)!
Ponto de Paragem
Regra Geral
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.
Obter uma soluo de como o problema pode ser dividido em passos menores
2.
3.
4.
5.
Utilizar recursividade ou no ?
849:1
7:/936/;2
<:27="7>?<@
;A:'4(9
7CBD6/EB
FGHIJ
KL MLNONG
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);
}
PLQRI
ORGQKNGSJ
TRJOU"OVWTX
SYR'L(Q
OCZDNGEZ
[\]^_
`a bacdc\
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.
eafg^
dg\f`c\h_
ig_dj"dklim
hng'a(f
dpoqc\ro
stuvw
xy 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{tw
w|"|
'y(~
|CD{tE
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; }
}
"
'(
,C
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 );
}
"
'(
,C
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:
n
i =1
(i * i )
Mtodo Recursivo
#include <iostream>
long int sumatorio(int num);
long int sumatorio (int num)
{
if (num == 0)
return(0L);
else
return( num * num + sumatorio( num 1 );
}
"
'(
CDE