按非案例类的字段排序 PriorityQueue
Posted
技术标签:
【中文标题】按非案例类的字段排序 PriorityQueue【英文标题】:Ordering a PriorityQueue by a field of a non-case class 【发布时间】:2017-10-31 19:41:41 【问题描述】:我目前正在尝试使用 scala 实现霍夫曼算法。为此,我想我会使用 PriorityQueue 根据它们的权重对树中的不同节点进行排序。因此,我必须创建 BinarySearchTree 节点的 PriorityQueue。但是,Scala 只允许我按案例类的字段排序。
这是我想要的:
class BinarySearchTree(weight: Int)
case class ForkNode(left: BinarySearchTree, right: BinarySearchTree, chars: List[Char], weight: Int) extends BinarySearchTree(weight)
case class LeafNode(char: Char, weight: Int) extends BinarySearchTree(weight)
def createBST(inputFile: ListMap[Char,Int]): BinarySearchTree =
def weightOrder(t2: BinarySearchTree) = t2.weight
val nodeMap:PriorityQueue[BinarySearchTree] = PriorityQueue(Ordering.by(weightOrder))
null
但它不能编译。但是,def weightOrder(t2: ForkNode) = t2.weight
确实可以编译,但这不是我想要的。
如何根据非案例类中的字段对我的优先级队列进行排序?
【问题讨论】:
你可以把 val 放在你的类中的权重之前(否则权重只是构造函数的参数,而不是成员),或者更好地使用特性而不是类 @dk14 现在该行已编译,但现在 nodeMap 声明行给出了发现的编译错误: scala.math.ordering[BinarySearchTree] required: BinarySearchTree... 有什么想法吗? @SimonBearsPriorityQueue.apply[T](T*)(Ordering[T]): PriorityQueue[T]
。当您致电PriorityQueue.apply(Ordering.by(...))
时,它认为您正在尝试创建PriorityQueue[Ordering[BinarySearchTree]]
。我认为空括号可能会起作用:PriorityQueue()(Ordering.by(...))
,但如果不是,这肯定会:PriorityQueue.apply(Seq[BinarySearchTree](): _*)(Ordering.by(...))
。
【参考方案1】:
这是不完整的,但可以编译。
import scala.collection.immutable.ListMap
import collection.mutable.PriorityQueue
class BinarySearchTree(val weight: Int) //weight is now member data
case class ForkNode( left: BinarySearchTree
, right: BinarySearchTree
, chars: List[Char]
, override val weight: Int //now needs override
) extends BinarySearchTree(weight)
case class LeafNode( char: Char
, override val weight: Int //now needs override
) extends BinarySearchTree(weight)
def createBST(inputFile: ListMap[Char,Int]): BinarySearchTree =
def weightOrder(t2: BinarySearchTree) = t2.weight
val bst: BinarySearchTree = LeafNode('c',2) //build something of proper type
val nodeMap:PriorityQueue[BinarySearchTree] =
PriorityQueue(bst)(Ordering.by(weightOrder)) //create PriorityQueue
null //etc.
PriorityQueue
是可变的并且类型不变,所以如果你想要 PriorityQueue[BinarySearchTree]
,那么构造函数参数必须是 BinarySearchTree
类型而不是派生类型(即节点)。
【讨论】:
你必须用 LeafNode 构建它吗? PriorityQueue 不能在声明时为空吗? 我使用LeafNode()
只是为了说明。可以是null
。编译器只需将其识别为类型BinarySearchTree
。
如果为null,是否为空优先队列?
可以,不过你也可以传一个空参数:PriorityQueue()(Ordering.by(weightOrder))
以上是关于按非案例类的字段排序 PriorityQueue的主要内容,如果未能解决你的问题,请参考以下文章
在C ++中按非ASCII顺序的第一个字母对字符串向量进行排序