Scala 问题对 Stack[A] 使用 PriorityQueue 非默认排序
Posted
技术标签:
【中文标题】Scala 问题对 Stack[A] 使用 PriorityQueue 非默认排序【英文标题】:Scala problem using PriorityQueue non-default ordering for Stack[A] 【发布时间】:2010-11-29 04:12:56 【问题描述】:我正在尝试使用 Scala 编写耐心排序的简单实现。 我已经正确地创建了初始桩;但是,我使用优先级队列来简化输出列表的生成让我很头疼。
看来我的排序实现要么错误,要么被忽略:
def PileOrdering = new Ordering[Stack[A]]
def compare(a : Stack[A], b : Stack[A]) = a.head.compare(b.head)
// Use a priority queue, ordering on stack heads (smallest stack elems)
val pq = new PriorityQueue[Stack[A]]()(PileOrdering)
// piles is a List[Stack[A]]
pq ++= piles
// Extract an ordered list of elements
val returnVal = (0 until count) map (_ =>
val smallestList = pq.dequeue
val smallestVal = smallestList.pop
if (smallestList.length > 0)
pq.enqueue(smallestList)
smallestVal
)
PriorityQueue 似乎是按(我想是默认的堆栈排序)堆栈大小排序的,而不是我的排序。
有什么明显错误的地方跳出来吗? 任何帮助都会受到极大的欢迎。 谢谢,
编辑:我在最初的问题中没有说清楚:我使用的是 Scala 2.8.1。Edit2:我期待 returnVal包含从最小到最大的元素排序,通过从所有堆栈的头部获取最小元素来找到。 Daniel 指出,我的 Ordering 将从最大到最小的 Stacks 排序(堆栈本身已经正确排序,最小的元素在顶部),这似乎是问题所在。
【问题讨论】:
请提供可编译代码。这个不会编译,因为A
和count
都是未知的。
是的,你是对的。我想这就是在凌晨提出问题的问题。我现在不在家,但稍后我会在我在家时编辑问题。
请明确returnVal
中的代码应该做什么——否则很难知道你的代码是否“错误”。 :-)
【参考方案1】:
您不会对优先级队列中的第一个元素是具有 最大 值的元素感到困惑吗?代码似乎期望第一个元素是具有最小值的元素。
【讨论】:
我怀疑你是对的;我必须检查我在家里使用的具体值,但是我认为是的。【参考方案2】:很难回答发生了什么,因为您没有包含整个程序的输入和输出。我的猜测是,这是由于 2.8.1 中 PriorityQueue
的旧实现。以下程序使用自定义排序,并使用堆栈列表填充优先级队列:
import collection._
import collection.mutable.PriorityQueue
import collection.mutable.Stack
class Test[A](piles: Traversable[Stack[A]])(implicit ord: Ordering[A])
def PileOrdering = new Ordering[Stack[A]]
def compare(a : Stack[A], b : Stack[A]) = ord.compare(a.head, b.head)
// Use a priority queue, ordering on stack heads (smallest stack elems)
val pq = new PriorityQueue[Stack[A]]()(PileOrdering)
// piles is a List[Stack[A]]
pq ++= piles
object Main
def main(args: Array[String])
val t = new Test(Seq(Stack(1, 2, 3), Stack(15, 8), Stack(3, 4, 9, 0, -1), Stack(45, 1, 2, 3, 4)))
while (t.pq.nonEmpty)
println(t.pq.dequeue)
程序输出:
Stack(45, 1, 2, 3, 4)
Stack(15, 8)
Stack(3, 4, 9, 0, -1)
Stack(1, 2, 3)
使用 Scala 主干,这似乎是正确的。我应该指出,PriorityQueue
进行了一些更改,出于二进制兼容性的原因,这些更改未包含在 2.8.1 中,但将在 2.9 中提供:
apply
和 update
无法有意义地实现
调用toString
或遍历元素不会产生堆顺序- 获得它的唯一方法是使用dequeue
【讨论】:
是的,发布一个例子肯定是明智的......当我回到家时,我必须检查我的具体例子发生了什么,但运行你的例子(在 2.8.1 上)给我这个: Stack(8, 15) Stack(4, 3, 2, 1, 45) Stack(3, 2, 1) Stack(-1, 0, 9, 4, 3) 这似乎只是表明初始化。堆栈的顺序已更改。完全有可能我误解了我之前得到的输出 - Daniel 指出我粘贴的代码甚至无法编译,我早上那个时候显然没有清晰的头脑!感谢您的回答!以上是关于Scala 问题对 Stack[A] 使用 PriorityQueue 非默认排序的主要内容,如果未能解决你的问题,请参考以下文章