Pular para o conteúdo

Como Utilizar a Recursão para Verificar a Igualdade de Ab em Python

[

Recursividade em Python: Uma Introdução

por Nome do autor python

Pode parecer estranho uma função chamar a si mesma, mas muitos tipos de problemas de programação são melhor expressos de forma recursiva. Quando você se depara com um problema desses, a recursividade é uma ferramenta indispensável que você deve ter no seu arsenal.

Ao final deste tutorial, você vai entender:

  • O que significa uma função chamar a si mesma recursivamente
  • Como o design das funções em Python suporta a recursividade
  • Quais fatores considerar ao decidir se deve ou não resolver um problema de forma recursiva
  • Como implementar uma função recursiva em Python

Em seguida, você estudará vários problemas de programação em Python que utilizam a recursividade e irá comparar a solução recursiva com uma solução não-recursiva equivalente.

O que é Recursividade?

A palavra recursividade vem do latim recurrere, que significa correr ou voltar apressadamente, retornar, reverter ou recorrer. Aqui estão algumas definições online de recursividade:

  • Dictionary.com: O ato ou processo de retornar ou voltar
  • Wiktionary: O ato de definir um objeto (geralmente uma função) em termos desse próprio objeto
  • The Free Dictionary: Um método para definir uma sequência de objetos, como uma expressão, função ou conjunto, em que alguns objetos iniciais são dados e cada objeto sucessivo é definido em termos dos objetos anteriores

Uma definição recursiva é aquela em que o termo definido aparece na própria definição. Situações de autorreferência surgem frequentemente na vida real, mesmo que nem sempre sejam imediatamente reconhecíveis como tal. Por exemplo, suponha que você queira descrever o conjunto de pessoas que compõem seus ancestrais. Você pode descrevê-los dessa maneira:

Observe como o conceito que está sendo definido, ancestrais, aparece em sua própria definição. Essa é uma definição recursiva.

Na programação, a recursividade tem um significado muito preciso. Refere-se a uma técnica de codificação em que uma função chama a si mesma.

Por que usar a Recursividade?

A maioria dos problemas de programação é solucionável sem recursividade. Portanto, estritamente falando, a recursividade geralmente não é necessária.

No entanto, algumas situações se prestam especialmente bem à recursividade. Quando um problema pode ser dividido em subproblemas menores, e a solução para cada subproblema é semelhante à solução geral, a recursividade proporciona uma maneira elegante de resolver o problema.

Existem várias vantagens e razões para usar a recursividade em Python:

  • Expressividade: em muitos casos, uma solução recursiva é mais fácil de entender e implementar do que uma solução iterativa.
  • Simplificação do código: a recursividade permite resolver problemas complexos de maneira mais simples, dividindo-os em subproblemas menores.
  • Redução de repetição de código: ao dividir um problema em subproblemas menores, você pode reutilizar a mesma função recursiva para resolver cada subproblema.
  • Solução geral elegante: em alguns casos, a solução recursiva pode ser a melhor abordagem para resolver um determinado problema ou fornecer uma solução mais eficiente.

É importante ressaltar que nem todos os problemas podem ou devem ser resolvidos de forma recursiva. Existem casos em que a recursividade pode levar a um desempenho ruim ou a estouros de pilha (quando a pilha de chamadas da função fica sem espaço). Portanto, é essencial avaliar cuidadosamente os requisitos e características do problema antes de optar por uma solução recursiva.

Exemplo: Contagem Regressiva até Zero

Vamos começar com um exemplo simples para entender a recursividade em Python: uma função para contar de um número até zero. A ideia é que, dado um número, a função começará imprimindo o número e, em seguida, chamará a si mesma com o número anterior até chegar a zero.

def countdown(n):
if n <= 0:
return
print(n)
countdown(n - 1)
countdown(5)

Neste exemplo, a função countdown verifica se o número n é menor ou igual a zero. Se for, a função retorna sem fazer nada. Caso contrário, ela imprime o número n e chama a si mesma com o número n - 1. Esse processo se repete até que n seja igual a zero, momento em que a função retorna e a recursão é encerrada.

Ao chamar countdown(5), a função imprimirá os números 5, 4, 3, 2, 1 e, finalmente, encerrará a recursão quando chegar a zero.

Exemplo: Cálculo do Fatorial

Um exemplo clássico de problema que pode ser resolvido de forma recursiva é o cálculo do fatorial de um número. O fatorial de um número inteiro n é o produto de todos os números inteiros positivos menores ou iguais a n. Por exemplo, o fatorial de 5 (indicado por 5!) é igual a 5 * 4 * 3 * 2 * 1 = 120.

Podemos escrever uma função recursiva para calcular o fatorial de um número da seguinte forma:

def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
result = factorial(5)
print(result)

Nesta função, verificamos se n é igual a zero. Se for, retornamos 1, pois o fatorial de zero é definido como 1. Caso contrário, retornamos o produto de n pelo fatorial de n-1, calculado chamando a própria função recursiva factorial. Assim, a função se chama repetidamente com valores menores de n até chegar a zero, quando a recursão é encerrada.

Ao chamar factorial(5), a função retorna o valor 120, que é o fatorial de 5.

Exemplo: Traversing de uma Lista Aninhada

Outro exemplo interessante de uso da recursão é o percurso de uma lista aninhada, ou seja, uma lista que contém outras listas como seus elementos. Vamos considerar o seguinte exemplo:

nested_list = [1, 2, [3, 4], [5, [6, 7]]]
def traverse_list(lst):
for item in lst:
if isinstance(item, list):
traverse_list(item)
else:
print(item)
traverse_list(nested_list)

Neste exemplo, temos a lista nested_list que contém elementos simples (1, 2) e elementos que são outras listas ([3, 4], [5, [6, 7]]). A função traverse_list percorre a lista de entrada e, se encontrar um elemento que é outra lista, chama a si mesma recursivamente para percorrer essa lista aninhada. Se encontrar um elemento simples, imprime o valor na tela.

Ao chamar traverse_list(nested_list), a função percorrerá a lista aninhada e imprimirá na tela os elementos 1, 2, 3, 4, 5, 6 e 7.

Esses são apenas alguns exemplos de como a recursividade pode ser usada para resolver problemas em Python. É importante destacar que a recursividade pode não ser a melhor abordagem para todos os problemas e que é necessário ter um cuidado especial com o desempenho e a profundidade da recursão. No entanto, em muitos casos, a recursão pode ser uma ferramenta poderosa e elegante para solucionar problemas complexos de forma simples e concisa.