其他的答案真的不回答究竟为什么你的代码不正确。看起来你正在处理的情况是,当列表b
是空的和非空的,并且一切都应该没问题,但事实上你并不是。让我们再看看您的代码,并进行一些格式修复。
def subset(a: List[Int], b: List[Int]): Boolean = {
(a, b) match {
case (_, Nil) => return true
} // we can never make it past here, because either we return true,
// or a MatchError is raised.
b match {
case h :: t if (a.contains(h)) => subset(a,t)
case h :: t => return false
}
}
这里真正的问题是,您有两个完全断开的match
语句。所以当b
非空时,第一个匹配将失败,因为它只处理b
为Nil
时的情况。
正如在其他解决方案中指出的那样,正确的方法是将两个match
语句合并为一个。
def subset(a: List[Int], b: List[Int]): Boolean = {
(a, b) match {
case (_, Nil) => true
case (xs, head :: tail) if(xs contains head) => subset(xs, tail)
case _ => false
}
}
请注意return
语句不再需要。在scala中,你应该尽可能避免使用return
,因为你的思考方式实际上可能导致你进入这个陷阱。早期返回的方法可能会导致错误,并且难以阅读。
一个更清晰的实现方法可以使用diff
。如果b
的元素组减去a
的元素为空,则b
可以被认为是a
的子集。
def subset(a: List[Int], b: List[Int]): Boolean = (b.distinct diff a.distinct).nonEmpty
distinct
如果有可能为a
和b
包含重复时才需要,因为我们正在尝试一种List
像Set
时,它实际上不是。
更好的是,如果我们将List
s转换为Set
s,那么我们可以使用subsetOf
。
def subset(a: List[Int], b: List[Int]): Boolean = b.toSet.subsetOf(a.toSet)
请注意,一个更复杂的类型系统可能会认识到只有非零的'b'的情况才能逃过第一场比赛。 – 2015-02-08 22:29:53