【问题标题】:Moving elements in a priority queue to a lower level将优先级队列中的元素移动到较低级别
【发布时间】:2023-04-04 06:37:02
【问题描述】:

我有一个多级优先级队列,它被实现为 (level:int, priority:int, 'a) 的列表。数据类型如下所示:

datatype 'a queue = NONE | Q of (int * int * 'a) list;

较低级别的元素位于队列的前面。同一级别的元素按优先级排序。我有一个入队函数

所以,如果现有队列是:val a = Q [(3,2,"c"),(3,2,"d"),(5,2,"b"),(5,3,"a")], 然后,将 1 5 "e" 排入队列 给了

val a = Q [(1,5,"e"),(3,2,"c"),(3,2,"d"),(5,2,"b"),(5,3,"a")]

我必须编写一个函数 move ,它对谓词 p 进行操作,它将所有满足谓词 p 的元素移动到 q 内的较低级别的队列中。 那就是: val move : ('a -> bool) -> 'a queue -> 'a queue 下面的定义是行不通的。

fun move pred (Q((l,p,v)::xs)) =  if (pred (v)) then enqueue (Q xs) (l-1) p v else (move pred (Q xs))
  | move pred (Q[]) = raise Empty

我刚开始学习 sml。请帮忙。

【问题讨论】:

    标签: functional-programming queue priority-queue sml smlnj


    【解决方案1】:

    首先,有一个名为 NONE 的构造函数是不好的,因为它会覆盖 同名的内置选项类型值。其次,你说元素为 谓词满足的应该移到较低的级别 - 是那个级别 总是比之前的水平低一个?

    您的move 将不起作用,因为您显然没有递归调用它 当pred v 为真时,只有当它不是时。如果您将(l,p,v) 排入队列 递归调用move pred 的队列(即move pred (Q xs) 而不是Q xs),也许它会更好。

    还要注意,这个问题非常适合通过折叠来解决:

    fun move pred (Q elems) =
        let fun enq ((l,p,v), q) = enqueue q (if pred v then l-1 else l) p v
        in foldl enq (Q []) elems end
    

    【讨论】:

    • 感谢关于 NONE 的建议。
    • 感谢您将我指向 foldl 并指出我在递归方面的错误。确实很有帮助。
    • 本质上,您将优先级队列中的每个元素重新添加到新的空队列中。由于您将 Q [] 指定为基础,因此折叠版本使这一点更加明显。我还相信,您提出异常的基本情况是不够的,因为从列表中删除三元组的所有递归最终都会到达空列表。您可能想重新考虑在空队列中移动所有元素意味着什么(这不应该是非法的)。
    【解决方案2】:

    fun move pred (Q((l,p,v)::xs)) = if (pred (v)) then enqueue (Q xs) (l-1) p v else enqueue (move pred (Q xs) ) l p v | move pred (Q[]) = raise Empty 这也有效!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多