Saturday, May 12, 2012

Detección de palíndromos en Scala

Mi primera, y pequeña, contribución a Rosetta Code: la versión recursiva de la detección de palíndromos en Scala:

def isPalindrome(s : String) : Boolean = s match {
  case s if s.length > 1 => (s.head == s.last) && isPalindrome(s.slice(1, s.length-1))
  case _ => true
}

Y aquí un pequeño ejemplo de uso:

scala>isPalindrome("holaloh")
res4: Boolean = true

Breve explicación de su funcionamiento:
  • def isPalindrome(s : String) : Boolean Definimos una función, llamada isPalindrome, que toma como entrada una cadena y devuelve un booleano. 
  • s match { ...} Usaremos emparejamiento de patrones (pattern matching). No es la única forma, ni mucho menos, de escribir esta función, pero yo diría que es la más idiomática en Scala (aparte de la versión no recursiva que aparece en Rosetta Code, que es sin duda la opción más sencilla).
  • case s if s.length > 1 Si la cadena s tiene longitud > 1
  • => (s.head == s.last) && isPalindrome(s.slice(1, s.length-1)) La función devuelve cierto si el primer carácter de la cadena es igual al último, y si el resto de la cadena (lo que está entre el primer carácter y el último sin incluirlos) es también un palíndromo
  • case _ => true En otro caso la función devuelve cierto (esto se emparejará con cadenas de longitud <= 1, y todas esas las consideramos palíndromos, incluyendo la cadena vacía).
Si nos pasan null como parámetro, la función terminará con una excepción de tipo NullPointerException, porque intentará averiguar si un null tiene longitud > 1. Para protegernos, podríamos añadir otro case al match (tendría que ser el primero): case null => false

Las cadenas en Scala son Strings de Java, pero tienen métodos añadidos para soportar todas las operaciones de las secuencias de Scala (Seq) (por eso podemos usar head, last o slice).

El emparejamiento de patrones da muchísimo más juego, esto apenas da una pequeña idea de la sintaxis que tiene y lo que se puede hacer en Scala.

No comments: