我是 Scala 新手,我看到人们访问案例类的唯一方法是使用模式匹配。
我最近用以下代码解决了霍夫曼编码问题
abstract class TreeNodes
case class Leaf(weight: Int, value: String) extends TreeNodes
case class Node(weights: Int, left: TreeNodes, right: TreeNodes) extends TreeNodes
// P50
def huffman(freq: List[(String,Int)]): List[(String,String)] = {
def makeNode(left: TreeNodes, right: TreeNodes): Node =
(left,right) match
case (Leaf(w1,_),Leaf(w2,_)) => Node(w1 + w2, left,right)
case (Node(w1,_,_),Leaf(w2,_)) => Node(w1 + w2, left ,right)
case (Leaf(w1,_), Node(w2,_,_)) => Node(w1 + w2, left, right)
case (Node(w1,_,_), Node(w2,_,_)) => Node(w1 + w2, left, right)
def makeLeaves(freq: List[(String,Int)]): List[TreeNodes] = freq.map((s: String, i: Int) => Leaf(i,s))
def makeTree(nodes: List[TreeNodes]): List[TreeNodes] = {
if nodes.size == 1 then nodes else {
val sortedNodes = nodes.sortBy(_ match {case Leaf(w,_) => w; case Node(w,_,_) => w})
makeTree(sortedNodes.appended(makeNode(sortedNodes.head,sortedNodes.tail.head)).drop(2))
}
}
def traverseTree(node: TreeNodes, acc: String): List[(String, String)] = {
node match
case Leaf(w, s) => List((s,acc))
case Node(w, left, right) => traverseTree(left, acc + "0") ::: traverseTree(right, acc + "1")
}
traverseTree(makeTree(makeLeaves(freq)).head, "").sortBy(_._1)
}
输入和输出应该像这样:
scala> huffman(List(("a", 45), ("b", 13), ("c", 12), ("d", 16), ("e", 9), ("f", 5)))
res0: List[String, String] = List((a,0), (b,101), (c,100), (d,111), (e,1101), (f,1100))
代码正确并产生所需的输出。但是,我想将
makeNode
函数重构为更干净的版本,因为所有情况都有相同的返回值。
我想要一个更简洁的版本。 有没有办法为不同的案例类创建公共字段或以任何其他方式访问案例类而无需模式匹配?
只需在公共接口中声明公共方法即可,在本例中,将
def weight: Int
或 val weight: Int
添加到基类中。
在 Scala 2.x 中:
sealed abstract class TreeNodes {
def weight: Int
}
case class Leaf(weight: Int, value: String) extends TreeNodes
case class Node(weight: Int, left: TreeNodes, right: TreeNodes) extends TreeNodes
//...
def makeNode(left: TreeNodes, right: TreeNodes): Node =
Node(left.weight + right.weight, left,right)
在 Scala 3.x 中:
enum TreeNodes:
case Leaf(weight: Int, value: String)
case Node(weight: Int, left: TreeNodes, right: TreeNodes)
def weight: Int
但如果您希望其余代码按原样工作,请记住导入
Leaf
和 Node
:import TreeNodes._
。