有人可以向我解释方法union
在此代码中的确切作用吗?我可以看到它在功能中呼唤自己,但除此之外,我不知道它做了什么。打印t2 union t3
会产生{{{.-1.}2.}3{{.4.}5{.7.}}}
。
object Mp6 {
def main(args: Array[String]): Unit = {
val t1 = Empty
val t2 = t1 incl 3 incl 5 incl 4 incl 7
val t3 = t2 incl 2 incl 4 incl -1
println(t1)
println(t2)
println(t1 contains 5)
println(t2 contains 5)
println(t2 contains 5)
println(t2 union t3)
}
}
abstract class IntSet {
def incl(x: Int): IntSet
def contains(x: Int): Boolean
def union(other: IntSet): IntSet
}
object Empty extends IntSet {
def contains(x: Int): Boolean = false
def incl(x: Int): IntSet = new NonEmpty(x, Empty, Empty)
def union(other: IntSet): IntSet = other
override def toString = "."
}
class NonEmpty(elem: Int, left: IntSet, right: IntSet) extends IntSet {
def contains(x: Int): Boolean =
if (x < elem) left contains x
else if (x > elem) right contains x
else true
def incl(x: Int): IntSet =
if (x < elem) new NonEmpty(elem, left incl x, right)
else if (x > elem) new NonEmpty(elem, left, right incl x)
else this
def union(other: IntSet): IntSet = {
val set = left.union(right.union(other))
set.incl(elem)
}
override def toString = "{" + left + elem + right + "}"
}
答案 0 :(得分:2)
好吧,你基本上要求解释评估的替换模型是如何工作的。如上面的评论中所述,您的代码段非常类似于Martin Odersky(Scala的创建者)编写的IntSets
的实现,因此我将使用其课程笔记中的符号。我假设您已经快速阅读了替换模型规则。如果没有,Functional Programming Principles in Scala和Scala by Example是开始的好地方。
我会给你一个提示:为了方便起见,假设val t1 = new NonEmpty(1, Empty, Empty)
和val t2 = new NonEmpty(2, Empty, new NonEmpty(3, Empty, Empty))
。这意味着t1: NonEmpty = {.1.}
和t2: NonEmpty = {.2{.3.}}
。现在让我们评估表达式t1 union t2
。
t1 union t2 = new NonEmpty(1, Empty, Empty) union new NonEmpty(2, Empty, new NonEmpty(3, Empty, Empty))
→ [1/elem, Empty/left, Empty/right] [new NonEmpty(2, Empty, new NonEmpty(3, Empty, Empty))/other] [new NonEmpty(1, Empty, Empty)/this] (left union (right union other)) incl elem
= (Empty union (Empty union new NonEmpty(2, Empty, new NonEmpty(3, Empty, Empty)))) incl 1
...
您现在可以完成评估吗?
答案 1 :(得分:0)
它是一个排序整数集的实现,它通过使用不添加重复项的二进制排序树进行备份来工作。因此,union只执行一个集合理论联合,其中整数的顺序被保留。