【问题标题】:insertSorted comparison function in SML NJSML NJ 中的 insertSorted 比较函数
【发布时间】:2021-03-23 10:51:16
【问题描述】:

我之前已经发布过类似的问题,但我认为我需要重新表述我的问题。在我想要完成的事情上,我早些时候得到了一些很大的帮助。

所以,我现在想知道的是如何在我的代码中传递 comp 函数,以便它可以自定义。

我希望能够跑步

insertSorted(5, fn(a, b) => a > b, [8, 6, 3, 1];

哪个会返回

val it = [8, 6, 5, 3, 1]

同时还可以翻转标志并能够运行

insertSorted(5, fn(a, b) => a < b, [8, 6, 3, 1];

哪个会返回

val it = [1, 3, 5, 6, 8]

这是我目前所拥有的:

* insertSorted *
fun insertSorted (x, comp, nil) = [x]
 |  insertSorted (x, comp, y::ys) = if x comp y then y::x::ys else y :: insertSorted (x,ys);

这是有问题的“comp”: 第 2 行: if x comp y then y::x::ys else y :: insertSorted (x,ys);

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    在我看来,insertSorted 可能是两件事: (a) 一个假设其输入列表按照与给定的相同关系排序的函数,因此插入是 O(n),或者(b) 一个函数,它首先根据关系对输入列表进行排序,然后插入元素。

    我认为 (a) 是有道理的,尽管它有点脆弱,而 (b) 有点糟糕:

    如果允许您假设您的输入已经排序,那么您的函数是 O(n) 而不是 O(n log n)。您可以将此数据结构称为预排序列表。现在,没有什么可以阻止您将未排序的列表提供给insertSorted,这样可能会导致错误。有一些方法可以克服这一点。但那是另一个话题了。

    如果这就是你想要的,那么这就是如何做到的:

    fun insertSorted (x, comp, y::ys) =
          if comp (x, y)
          then y :: insertSorted (x, comp, ys)
          else x :: y :: ys
      | insertSorted (x, _, []) = [x]
    

    对此进行测试:

    - insertSorted (5, op <, [8,7,6,4,3,2]);
    val it = [8,7,6,5,4,3,2] : int list
    
    - insertSorted (5, op >, [2,3,4,6,7,8]);
    val it = [2,3,4,5,6,7,8] : int list
    

    如果您不假设您的输入已经排序,那么insertSorted 是一个非常糟糕的名称:我们不会插入已排序的内容。此外,由于我们无论如何都需要对整个输入进行排序,因为 O(n log n),所以 then 插入一个额外的 O( n),除非我们可以假设输入是“几乎”排序的,在这种情况下,某些排序算法比其他算法更好。

    假设“未排序”与“排序”相反,并且由于您使用带有排序功能的SML/NJ,您可以做的是:

    fun insertUnsorted (x, comp, ys) =
      ListMergeSort.sort comp (x::ys)
    

    对此进行测试:

    - insertUnsorted (5, op <, [1,9,3,4,6,2]);
    val it = [9,6,5,4,3,2,1] : int list
    
    - insertUnsorted (5, op >, [1,9,3,4,6,2]);    
    val it = [1,2,3,4,5,6,9] : int list
    

    sort相比,我认为这个功能不是很有用。

    有关 SML/NJ 以外的其他 SML 编译器中的排序函数,请参阅this answer

    【讨论】:

    • 非常感谢,这提供了如此清晰的信息。是的,A 是正确的假设
    • 我也同意这不是最有用的功能。这只是我被分配的一个更大项目的一部分。
    • 学校项目应该是一个很好的借口,用好的选择来过度设计,比如用你找到的任何技术 og 设计模式替换所有内部结构。
    猜你喜欢
    • 1970-01-01
    • 2012-03-12
    • 2013-09-30
    • 2014-02-23
    • 2014-03-19
    • 2010-10-23
    • 1970-01-01
    • 2016-02-02
    • 2011-11-24
    相关资源
    最近更新 更多