2015-10-18 48 views
0

我一直在努力提升自己的Scala知識。 我想遞歸實現這個函數,但有困難。使用Scala進行函數式編程

enter image description here

我的主要問題是,你怎麼能接受在可以接受的列表或數字的參數列表。

+0

'List [Any]'會去。 – ayvango

+0

這是我到目前爲止,但它不工作。 DEF深度(L:列表[任意]):INT = { \t \t爲(I' - 1){ \t \t \t我匹配{ \t \t \t \t情況下列表:列表[任意] => 1 +深度(列表) \t \t \t} \t \t} – roy

+1

而那不會。 'for(i < - l){}'給你'單位',而不是你想要的'Int'。爲了從'for'表達式中得到結果,你需要'產生'它們 – ayvango

回答

3

depth(x: Any): Int是你想要的簽名,然後x模式匹配,以確定它是否是一個List[_]與否,其中_表示你不關心什麼是在列表中。 (實際上,使用Seq[_]將是更慣用的Scala類型。)請注意,所示示例缺少一對parens,List(1, 2, List(3))...它也假定depth(8) == 0(例如)。

一個棘手的部分是,你不應該假設嵌套列表將是「父」列表中的第一個或最後一個元素,即...List(1,List(2,3),4)...是可能的。

最後一點值得一提;如果您正在構建「產品」depth方法,則值得擁有抽象與NodeLeaf具體類型,因此您可以使用更好的類型簽名depth(tree: Tree[_]): Int,以明確清楚何時代表樹結構的一部分vs 。樹中的數據。這裏使用List這個練習很方便,但是否則有點模棱兩可,因爲你可能有一些東西,其中一些節點實際上是列表。

+0

哦,是的。用變形抽象來殺死他 – ayvango

0

如果你堅持使用理解,我可以提供與它一起工作的實現。

首先定義兩個有用的類

import scala.collection.generic.CanBuildFrom 
import scala.collection.mutable.Builder 

class Folder[T](init : T, step : (T,T) => T) extends Builder[T,T] { 
    private[this] var state = init 
    override def += (elem : T) = { 
    state = step(state, elem) 
    this 
    } 
    override def clear() { 
    state = init 
    } 
    override def result() : T = state 
} 

class CanBuildFolder[F,T](init : T, step : (T,T) => T) extends CanBuildFrom[F,T,T] { 
    override def apply() : Builder[T,T] = new Folder(init, step) 
    override def apply(from : F) : Builder[T,T] = new Folder(init, step) 
} 

比你可以用用它們來理解

import scala.math.max 

object Test { 
    val example = List(1, List(2, 3), List(List(4, 5), 6, List(7, List(List(8), 9)))) 
    implicit val maxFolder = new CanBuildFolder[List[Any], Int](0, max) 

    def depth(source : List[Any]) : Int = 
    for (x <- source) yield x match { 
     case l : List[Any] => depth(l) + 1 
     case _ => 1 
    } 

    assert(depth(example) == 5) 
} 
1

我會盡量給在遞歸解決了一槍回答:

def depth(listOrNum: Any): Int = { 
    def help(y: Any, c: Int): Int = { 
    y match { 
     case y: Int => c 
     case List(curHead, rest @ _*) => 
     Math.max(help(curHead, c+1), help(rest, c)) 
     case _ => 0 
    } 
    } 
    help(listOrNum, 0) 
} 
1

collect在這裏很方便:

def depth(xs: List[Any]): Int = 
    1 + xs.collect{case xs: List[_] => depth(xs)} 
     .foldLeft(0)(_ max _) 

P.S.我同意迪恩關於List[Any]類型的評論是代表樹木的糟糕方式。 List[Any]是一種永遠不會出現在普通Scala代碼中的類型,所以我很難過看到它用於初學者的練習。