Scala中具有尾部函数的Max元素

时间:2014-12-23 19:06:47

标签: scala recursion functional-programming

我搞乱了Coursera的功能编程课程的作业,我偶然发现了一些奇怪的东西。此问题要求您仅使用方法isEmptyheadtail查找整数列表的最大值。我的解决方案是一个递归函数,如果没有更多元素,它会捕获UnsupportedOperationException。然而,解决方案似乎并不起作用,我认为这是因为异常永远不会被捕获。

  /**
   * This method returns the largest element in a list of integers. If the
   * list `xs` is empty it throws a `java.util.NoSuchElementException`.
   *
   * You can use the same methods of the class `List` as mentioned above.
   *
   * ''Hint:'' Again, think of a recursive solution instead of using looping
   * constructs. You might need to define an auxiliary method.
   *
   * @param xs A list of natural numbers
   * @return The largest element in `xs`
   * @throws java.util.NoSuchElementException if `xs` is an empty list
   */
  def max(xs: List[Int]): Int = 
  {
    def maxOfTwo(value1: Int, value2: Int) = {
      if(value1 > value2) value1
      else value2
    }
    println(xs.size)
    try { maxOfTwo(xs.head, max(xs.tail)) }
    catch { case noTail: UnsupportedOperationException => xs.head }
  }

当我使用以下代码时,只需将UnsupportedOperationException替换为Exception,一切都会完美无缺。我在这里错过了什么吗?

def max(xs: List[Int]): Int = 
  {
    def maxOfTwo(value1: Int, value2: Int) = {
      if(value1 > value2) value1
      else value2
    }
    println(xs.size)
    try { maxOfTwo(xs.head, max(xs.tail)) }
    catch { case noTail: Exception => xs.head }
  }

3 个答案:

答案 0 :(得分:2)

我认为这会更好:

  def max(xs: List[Int]): Option[Int] = {
    @tailrec
    def go(l: List[Int], x: Int): Int = {
      l match {
        case Nil    => x
        case h :: t => if (x > h) go(t, x) else go(t, h)
      }
    }
    if (xs.isEmpty) None else Some(go(xs.tail, xs.head))
  }

结果类型为Option,因为列表可以为空。

<强>更新

在使用UnsupportedOperationException时失败,因为当您尝试访问空列表的xs.head时,您还应该捕获NoSuchElementException。它适用于Exception,因为它是这两个例外的基类。

答案 1 :(得分:1)

您无法使用UnsupportedOperationException模式捕获java.util.NoSuchElementException。 顺便说一句,你的代码抛出异常两次。 catch块通过调用xs.head抛出第二个异常。

答案 2 :(得分:0)

只是思考功能呢?

def sum(xs: List[Int]): Int = {
  if (xs.isEmpty) 0 else xs.head + sum (xs.tail)  
}