Рекурсия в Scala

#scala #recursion

#scala #рекурсия

Вопрос:

Новичок в Scala и пытаюсь разобраться в рекурсии.

Наличие определений в моем сеансе:

 def inc(n: Int) = n   1
def dec(n: Int) = n – 1
  

Как я мог переопределить функцию ниже, чтобы использовать recursion inc и dec?

 add(n: Int, m: Int) = n   m
  

Мне интересно изучать как регулярную рекурсию, так и хвостовую рекурсию.

Спасибо

Комментарии:

1. Ни одна из этих функций не использует рекурсию. Каково ваше определение рекурсии? Рекурсия в Scala ничем не отличается от других языков, на самом деле

2. @cricket_007 Я в курсе. Пытаюсь найти решение, которое использует только recursion, inc, dec

3. Каков ваш ожидаемый результат для какого ввода?

4. add(2,2) должен возвращать 4

Ответ №1:

Как насчет этого:

 scala> def inc(n: Int) = n   1
inc: (n: Int)Int

scala> def dec(n: Int) = n - 1
dec: (n: Int)Int

scala> def add(n: Int, m: Int): Int = m match {
     |   case 0           => n
     |   case _ if m > 0  => add(inc(n), dec(m))
     |   case _           => add(dec(n), inc(m))
     | }
add: (n: Int, m: Int)Int

scala> add(100, 99)
res0: Int = 199

scala> add(100, -99)
res1: Int = 1
  

Или есть другое решение, которое является реализацией аксиом Пеано.

 scala> def add2(n: Int, m: Int): Int = m match {
     |   case 0           => n
     |   case _ if m > 0  => inc(add2(n, dec(m)))
     |   case _           => dec(add2(n, inc(m)))
     | }
add2: (n: Int, m: Int)Int
  

Ответ №2:

Насколько я понимаю, хвостовая рекурсия состоит из 3 частей:

  • Условие для завершения рекурсии
  • возвращаемое значение если условие выполнено, возвращаемое значение является одним (или производным от) параметров хвостовой рекурсивной функции
  • и вызов самого себя, если условие не выполнено.

пример:

 def inc(n: Int) = n   1
def dec(n: Int) = n - 1


def add(n:Int, m:Int, sum: Int):Int = {
  //condition to break/end the recursion
  if (m <= 0) {
    // returned value once condition is met. This is the final output of the recursion
    sum
  } else {
    //call to itself once condition is unmet
    add(inc(n), dec(m), n   m)
  }
}
  

как вы можете видеть, такое ощущение, что вы выполняете цикл while, но более функциональным способом.

при рекурсии вызовы являются стеком, что приводит к тому, что размер стека вызовов равен глубине рекурсивных вызовов (что может привести к исключению stackoverflowexception). при хвостовой рекурсии это похоже на то, как интерпретируется цикл while.

пример рекурсии:

 def addAllNumberFromNToZero(n:Int):Int = {
  if (m <= 0) {
    sum
  } else {
    n   add(n - 1)
  }
}
  

Ответ №3:

Используя обычную рекурсию, вы могли бы попробовать что-то вроде:

   def inc(n: Int) = n   1
  def dec(n: Int) = n - 1

  def add(n: Int, m: Int): Int = {
    if (m == 0) n
    else add(inc(n), dec(m))
  }
  

add Функция рекурсивно вызывает саму add себя, каждый раз увеличивая n и уменьшая m . Рекурсия останавливается, когда m достигает нуля, после чего m возвращается точка.