按非案例类的字段排序 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... 有什么想法吗? @SimonBears PriorityQueue.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的主要内容,如果未能解决你的问题,请参考以下文章

如何按非字段值过滤 Django 查询集

在C ++中按非ASCII顺序的第一个字母对字符串向量进行排序

有没有按非英文字母排序的标准方法?例如,罗马尼亚字母表是“a â b c ...” [重复]

MR案例:学生排序(单字段排序多字段排序)

MR案例:学生排序(单字段排序多字段排序)

MR案例:学生排序(单字段排序多字段排序)