Italo Info


Programa com recursividade

As linguagens de programação modernas disponibilizam estruturas de repetição para o programador. No entanto, é possível simular qualquer repetição com funções, procedimentos, ou métodos recursivos. Por isso, esse artigo mostra um exemplo construido com recursividade, sem nenhum comando de repetição.

Um pouco sobre recursividade

As funções e procedimentos recursivos são chamadas dentro da própria função ou procedimento.

Exemplo:


procedure recursividade;
begin
  recursividade;
end;

O procedimento recursividade é chamado no corpo do próprio procedimento. No entanto, esse procedimento recursivo gera um loop infinito. Isto é, leva o programa a travar. Por isso, normalmente, as funções ou procedimentos recursivos têm uma condição de parada para evitar o loop infinito.

Por exemplo: como criar um procedimento em pascal que imprime os números de um a um número informado pelo usuário?

Abaixo a solução com comando "for":

program IMP_NUMS; uses crt; procedure imprime_numeros( n : integer); begin for i := 1 to n do write( i,' ' ); end; begin clrscr; write( 'Informe um numero: ' ); readln( num ); imprime_numeros( num ); readln; end.

Abaixo a solução com procedimento recursivo:

program IMP_NUMS_RECURSIVO; uses crt; procedure imprime_numeros( n : integer; i : byte ); begin if ( i <= n ) then begin write( i,' ' ); imprime_numeros( n, i+1 ); end; end; begin clrscr; write( 'Informe um numero: ' ); readln( num ); imprime_numeros( num, 1 ); readln; end.

Perceba que nas duas soluções são necessárias uma variável contador que foi nomeada "i" e uma condição de parada que é quando o contador "i" torna-se igual ao número "n". Perceba que na versão recursiva o contador é inicializado com 1 e passado como segundo parâmetro para o procedimento "imprime_numeros", enquanto que, na versão não recursiva a variável contador é criada no próprio procedimento, necessitando apenas de um número como parâmetro. A variável contador, nas duas soluções, tem seu valor variado de 1 até o numero "n". Perceba também que o procedimento recursivo recebe um parâmetro a mais no programa principal. Ou seja, a variavel contador "i" é inicializada com valor 1 no programa principal.

Na função recursiva, o contador "i" é incrementado em 1 quando a função imprime_numeros é chamada de modo recursivo recebendo o parâmetro "i+1".

Abaixo um programa que fiz inteiramente com recursividade ( Sem nenhuma estrutura de repetição ):

Imagem capturada do programa:

Imagem do programa recursivo

O código fonte escrito em linguagem pascal:

program RECURSIVIDADE ; uses crt; type tvetor = array[ 1..100 ] of integer; procedure imprime_numeros( n : word; i : byte ); begin if ( i <= n ) then begin write( i,' ' ); imprime_numeros( n, i+1 ); end; end; procedure imprime_divisores( n : word; i : byte ); begin if ( i <= n div 2 ) then begin if ( n mod i = 0 ) then write( i,' ' ); imprime_divisores( n, i+1 ); end else write( n ); end; procedure eh_primo( n : word; i : byte; var eh : boolean ); begin if ( eh ) and ( i <= n div 2 ) then begin if ( n mod i = 0 ) then eh := false else eh_primo( n, i+1, eh ); end; end; procedure imprime_primos( n : word; i : byte ); var eh_p : boolean; begin if ( i <= n ) then begin eh_p := true; eh_primo( i, 2, eh_p ); if ( eh_p ) then write( i,' ' ); imprime_primos( n, i+1 ); end; end; procedure sorteia_numeros( var vet : tvetor; max : word; tam, i : byte ); begin if ( i <= tam ) then begin vet[ i ] := random( max ); sorteia_numeros( vet, max, tam, i+1 ); end; end; procedure imprime_vetor( vet : tvetor; tam, i : byte ); begin if ( i <= tam ) then begin write( vet[ i ], ' ' ); imprime_vetor( vet, tam, i+1 ); end; end; procedure eh_palindromo( palavra : string; i : byte; var eh : boolean ); begin if ( eh ) and ( i <= length( palavra ) div 2 ) then begin if ( palavra[ i ] <> palavra[ length( palavra ) - i + 1 ] ) then eh := false else eh_palindromo( palavra, i+1, eh ); end; end; function fatorial( n : word ) : word; begin if ( n = 1 ) then fatorial := 1 else fatorial := n * fatorial( n-1 ); end; function fibo( n : word ) : word; begin if ( n = 0 ) or ( n = 1 ) then fibo := 1 else fibo := fibo( n-1 ) + fibo( n-2 ); end; procedure imprime_serie_fibo( n : word; i : byte ); begin if ( i <= n ) then begin write( fibo( i ),' ' ); imprime_serie_fibo( n, i+1 ); end; end; procedure indice_do_maior( vet : tvetor; tam, i : byte; menor : integer; var indice : byte ); begin if ( i <= tam ) then begin if ( vet[ i ] < menor ) then begin indice := i; indice_do_maior( vet, tam, i+1, vet[ i ], indice ); end else indice_do_maior( vet, tam, i+1, menor, indice ); end; end; procedure ordena( var vet : tvetor; tam, i : byte ); var indice : byte; aux : integer; begin if ( i <= tam ) then begin indice := i; indice_do_maior( vet, tam, i+1, vet[ i ], indice ); aux := vet[ i ]; vet[ i ] := vet[ indice ]; vet[ indice ] := aux; ordena( vet, tam, i+1 ); end; end; procedure menu; begin clrscr; writeln( '********************* Menu *********************' ); writeln; writeln( ' (1) - Imprime numeros menores ou iguais a' ); writeln( ' (2) - Imprime os primos menores ou iguais a' ); writeln( ' (3) - Imprime divisores' ); writeln( ' (4) - Verifica se eh palindromo' ); writeln( ' (5) - Imprime fatorial' ); writeln( ' (6) - Imprime serie fibbonacci' ); writeln( ' (7) - Imprime ordenado' ); writeln( ' (0/Esq) - Sair' ); writeln; writeln( '************************************************' ); writeln; end; { ****** PROGRAMA PRINCIPAL ****** } procedure prog_principal; const VET_QUANT: integer = 20; VET_MAX : integer = 100; var op : char; num : word; palavra : string; eh_p : boolean; fat : word; vet : tvetor; vtam : byte; Begin menu; op := readkey; if ( op <> '0' ) and ( op <> #27 ) then begin case op of '1': begin write( 'Informe um numero: ' ); readln( num ); writeln; write( 'Numeros: ' ); imprime_numeros( num, 1 ); readln; end; '2': begin write( 'Informe um numero: ' ); readln( num ); writeln; write( 'Primos: ' ); imprime_primos( num, 1 ); readln; end; '3': begin write( 'Informe um numero: ' ); readln( num ); writeln; write( 'Divisores de ',num,': ' ); imprime_divisores( num, 1 ); readln; end; '4': begin write( 'Informe uma palavra: ' ); readln( palavra ); eh_p := true; eh_palindromo( palavra, 1, eh_p ); writeln; if ( eh_p ) then writeln( 'A palavra ',palavra,' eh palindromo' ) else writeln( 'A palavra ',palavra,' nao eh palindromo' ); readln; end; '5': begin write( 'Informe um numero: ' ); readln( num ); fat := fatorial( num ); writeln; writeln( 'O fatorial de ',num,' eh: ', fat ); readln; end; '6': begin write( 'Informe um número: ' ); readln( num ); writeln; write( 'Serie fibbonacci: ' ); imprime_serie_fibo( num, 0 ); readln; end; '7': begin sorteia_numeros( vet, VET_MAX, VET_QUANT, 1 ); writeln; write( 'Numeros sorteados: ' ); imprime_vetor( vet, VET_QUANT, 1 ); ordena( vet, VET_QUANT, 1 ); writeln; write( 'Numeros ordenados: ' ); imprime_vetor( vet, VET_QUANT, 1 ); readln; end; end; prog_principal; end; End; Begin prog_principal; End.

Baixe o código fonte aqui.

Finalizando...

É isso pessoal. Peço que quem tiver gostado, envie um comentário logo abaixo.

Até o próximo