Я пытаюсь реализовать рекурсивную функцию в Scala для вычисления максимального значения в списке.

def max(xs: List[Int]): Int = {
  if (xs.isEmpty) throw new java.util.NoSuchElementException("List is Empty")
  else
     max1(0,xs)

  def max1(num :Int, x : List[Int]) : Int = {
    if(x.isEmpty) return num 
    else if(num>x.head) max1(num,x.tail) 
    else
      max1(x.head,x.tail)
  }
}

Я пытаюсь реализовать код для выдачи ошибки, когда он получает пустой список в качестве входных данных и пытается получить максимальное значение списка рекурсивным способом, используя другую вспомогательную функцию.

ошибка: несоответствие типов; найдено : Требуемая единица измерения: Int


person Vijay Krishna    schedule 13.06.2016    source источник
comment
Я закрыл две функции, верно?   -  person Vijay Krishna    schedule 13.06.2016
comment
У вашего алгоритма есть основной недостаток: он дает неверный результат, когда ему дается список отрицательных целых чисел.   -  person jwvh    schedule 13.06.2016
comment
Рассмотрите возможность использования возвращаемого типа Option[Int] для пустого списка, а не выбрасывания.   -  person Kevin Meredith    schedule 14.06.2016
comment
В чем преимущество? Не будет ли выдаваться ошибка?   -  person Vijay Krishna    schedule 14.06.2016
comment
Генерация исключений нарушает прозрачность ссылок, что является очень полезным свойством для рассуждений о/ понимание кода.   -  person Kevin Meredith    schedule 14.06.2016
comment
Понял причину. Большое спасибо.   -  person Vijay Krishna    schedule 14.06.2016


Ответы (4)


Поместите определение max1 перед оператором if. Возвращаемое значение функции — это результат последнего оператора в ее теле. Как у вас сейчас, последний оператор - def, а его результат - Unit.

person Dima    schedule 13.06.2016
comment
Хорошо, попробуем поместить определение max1 перед оператором If. Но возвращаемое значение max1 — это Int, верно? - person Vijay Krishna; 13.06.2016
comment
max1 возвращаемое значение равно Int. Но последний оператор max не выполняет max1, он только определяет его. - person Dima; 13.06.2016
comment
Хорошо, большое спасибо. Понял концепцию, и код работает. - person Vijay Krishna; 13.06.2016

Вы можете использовать пользователя require()

Например, с этим более идиоматичным кодом рекурсии:

def max(xs: List[Int]): Int = {
  require( xs.nonEmpty, ">>> Empty List <<<" )

  def max1( num:Int, x:List[Int] ) : Int = x match {
    case Nil => num
    case y :: ys => max1( (if( num>y ) num else y), ys )
  }

  max1(0,xs)
}

Потом,

max(List())

возвращает: java.lang.IllegalArgumentException: требование не выполнено: >>> Пустой список ‹‹‹

person Keith Pinson    schedule 13.06.2016
comment
Что здесь делает строчный регистр y :: ys =› max1( (if( num›y ) num else y), ys )? - person Vijay Krishna; 14.06.2016
comment
Шаблон y :: ys соответствует списку (y — начало, ys — хвост), затем стрелка позволяет нам вызвать метод max1, используя y и ys в качестве головы и хвоста. Условие if просто позволяет нам увеличить максимальное найденное значение. - person Keith Pinson; 14.06.2016
comment
Понял, спасибо большое - person Vijay Krishna; 14.06.2016

Вы можете использовать этот код для решения этой проблемы.

object Maximum {
  def apply(numbers: List[Int]): Int = {
    if (numbers.isEmpty) throw new Exception("List shouldn't be empty")
    max(numbers)
  }

  private def max(numbers: List[Int], maxNumb: Int = 0): Int = numbers match {
    case x::xs => if (x > maxNumb) max(xs, x) else max(xs, maxNumb)
    case Nil => maxNumb
  }
}

Maximum(List(1,9,9,12,34))
Maximum(List())
person Made Raka    schedule 13.06.2016

Определять

trait XInt
case class N(i: Int) extends XInt
case object NoInt extends XInt

и при сопоставлении с шаблоном пустой список возвращает NoInt, а в противном случае экземпляр N.

person elm    schedule 14.06.2016