Recursive function to obtain vowels of a word (Scala)

0

I am trying to do an exercise in which we have to define a recursive function that is able to return a string with all the vowels of a string using another function that indicates whether a Char is vowel or not:

object ej8 {
  def esVocal(letra:Char):Boolean={
    var vocal:Boolean=false
    if(letra=='a' || letra=='e' || letra=='i' || letra=='o' || letra=='u')vocal=true
    return vocal
  }
  def vocales(cadena:String): String={}

I find it hard to see if the vocal function can be done recursively since it needs yes or yes of the esVocal function because it is the one that checks the letters one by one but I can not find a valid solution without being fill the pile or do strange things, thanks in advance.

    
asked by Javier Espinosa Pérez 18.10.2018 в 04:01
source

3 answers

0

I do not advise you to access the chain by index ( cadena.charAt ). It is not well seen in functional programming and, in many cases, there is a better alternative. For example, you can use s.head instead of s.charAt(0) , or s.tail instead of s.substring(1) ,

Likewise, in scala it is recommended not to use the return to exit a function, that is more typical of programming imperative .

Basically, what you need is to create a "filter" , something as simple as:

def vocales(cadena: String): String = cadena.filter(esVocal)

We can create it as a recursive function, passing a check function as an argument, something like this:

def filtro(s: String, f: (Char) => Boolean): String =
  if (s.isEmpty)
    ""
  else if (f(s.head))
    s.head + filtro(s.tail, f)
  else
    filtro(s.tail, f)

With what we would finally have:

def vocales(s: String) = filtro(s, esVocal)

The filter function can be applied to more objects. We can create a generic filter function that works for any type of sequence:

def filtro[A](s: Seq[A], f: (A => Boolean)): Seq[A] = 
  s match {
    case (x +: xs) if f(x) => x +: filtro(xs, f)
    case (_ +: xs) => filtro(xs, f)
    case Nil => Nil
  }

With this definition, our vocales function would look like this:

def vocales(s: String) = filtro(s, esVocal).mkString

By the way, the esVocal function could also be made simpler:

def esVocal(c: Char) = "aeiou" contains c
    
answered by 18.10.2018 / 11:18
source
1

You can implement the following pseudocode that provides a recursive mechanism in which 3 factors are taken into account: a string or string that is the source or main chain, the position in which you start to traverse the string or string, and Last the stack to which you will add elements.

Funcion obtenerVocales(Cadena fuente, Entero posicion, Pila pila) Devuelve Pila

    Si posicion < fuente.longitud Entonces
        caracter charActual = fuente[posicion];

            Si esVocal(charActual) Entonces
                pila.push(charActual)
            Fin Si

       Devolver obtenerVocales(fuente, posicion + 1, pila)
    Fin Si

    Devolver pila
Fin Funcion

If you only want to show or print the values then you should not use a stack and simply print on the screen when it is a vowel, you would only pass in the function the parameters of the string to obtain the vowels and the position in which it starts. A greeting! :)

Pd: I have no experience in Scala but I think that with this you can solve your problem.

    
answered by 18.10.2018 в 04:36
0

I think I have found a valid solution:

def vocales(cadena:String): String={
    if(esVocal(cadena.charAt(0)) && cadena.length()>1){
      return cadena.charAt(0)+vocales(cadena.substring(1))
    }
    else if(!esVocal(cadena.charAt(0)) && cadena.length()>1){
      return vocales(cadena.substring(1))
    }else{
      return cadena
    }
  }
    
answered by 18.10.2018 в 04:46