La recursivitat és un concepte fonamental en la programació funcional i és àmpliament utilitzada en F#. En aquest tema, aprendrem què és la recursivitat, com utilitzar-la en F#, i veurem alguns exemples pràctics. També discutirem els avantatges i desavantatges de la recursivitat i com evitar problemes comuns com la recursivitat infinita.

Què és la Recursivitat?

La recursivitat és una tècnica de programació on una funció es crida a si mateixa per resoldre un problema. Un problema es divideix en subproblemes més petits, i la funció recursiva es crida a si mateixa per resoldre aquests subproblemes fins que s'arriba a un cas base, que és una condició que atura la recursió.

Components de la Recursivitat

  1. Cas Base: La condició que atura la recursió.
  2. Cas Recursiu: La part de la funció que crida a si mateixa.

Exemple Bàsic: Factorial

El factorial d'un nombre n (denotat com n!) és el producte de tots els nombres enters positius menors o iguals a n. Per exemple, 5! = 5 * 4 * 3 * 2 * 1 = 120.

Implementació en F#

let rec factorial n =
    if n = 0 then 1
    else n * factorial (n - 1)

Explicació

  • Cas Base: Si n és 0, retornem 1.
  • Cas Recursiu: Si n no és 0, retornem n multiplicat pel factorial de n - 1.

Exemple d'ús

let result = factorial 5
printfn "El factorial de 5 és %d" result

Exemple Avançat: Seqüència de Fibonacci

La seqüència de Fibonacci és una sèrie de nombres on cada nombre és la suma dels dos anteriors. Els primers dos nombres de la seqüència són 0 i 1.

Implementació en F#

let rec fibonacci n =
    if n = 0 then 0
    elif n = 1 then 1
    else fibonacci (n - 1) + fibonacci (n - 2)

Explicació

  • Cas Base: Si n és 0, retornem 0. Si n és 1, retornem 1.
  • Cas Recursiu: Si n no és 0 ni 1, retornem la suma de fibonacci (n - 1) i fibonacci (n - 2).

Exemple d'ús

let result = fibonacci 10
printfn "El desè nombre de Fibonacci és %d" result

Avantatges i Desavantatges de la Recursivitat

Avantatges

  • Claredat: Les solucions recursives poden ser més fàcils d'entendre i escriure.
  • Divisió de Problemes: És ideal per a problemes que es poden dividir en subproblemes més petits.

Desavantatges

  • Eficiència: Les funcions recursives poden ser menys eficients que les iteratives, especialment si no es fa servir la recursivitat de cua.
  • Recursivitat Infinita: Si no es defineix correctament el cas base, la funció pot cridar-se infinitament, causant un desbordament de la pila.

Recursivitat de Cua

La recursivitat de cua és una forma especial de recursivitat on la crida recursiva és l'última operació que es fa en la funció. Això permet que el compilador optimitzi la recursió, evitant desbordaments de la pila.

Exemple: Factorial amb Recursivitat de Cua

let factorialTailRec n =
    let rec loop acc n =
        if n = 0 then acc
        else loop (acc * n) (n - 1)
    loop 1 n

Explicació

  • Cas Base: Si n és 0, retornem l'acumulador acc.
  • Cas Recursiu: Multipliquem l'acumulador acc per n i cridem loop amb n - 1.

Exemple d'ús

let result = factorialTailRec 5
printfn "El factorial de 5 (amb recursivitat de cua) és %d" result

Exercicis Pràctics

Exercici 1: Suma de Nombres

Escriu una funció recursiva que calculi la suma dels primers n nombres enters positius.

let rec sum n =
    if n = 0 then 0
    else n + sum (n - 1)

Exercici 2: Nombre de Fibonacci amb Recursivitat de Cua

Escriu una funció recursiva de cua que calculi el n-è nombre de Fibonacci.

let fibonacciTailRec n =
    let rec loop a b n =
        if n = 0 then a
        else loop b (a + b) (n - 1)
    loop 0 1 n

Conclusió

La recursivitat és una eina poderosa en la programació funcional que permet resoldre problemes complexos de manera elegant. Hem vist com implementar funcions recursives en F#, incloent-hi la recursivitat de cua per millorar l'eficiència. Practicar amb exercicis recursius t'ajudarà a comprendre millor aquest concepte i a aplicar-lo en situacions reals.

© Copyright 2024. Tots els drets reservats