【问题标题】:Sort list of tuples lexicographically按字典顺序对元组列表进行排序
【发布时间】:2018-10-24 00:24:05
【问题描述】:

我试图在标准 ML 中创建一个函数,该函数获取一个 string * int 列表并返回一个词典排序列表。

例如 foo [("y",5),("x",10)] 将返回 [("x,10),("y",5)](只有每个元组的第一个元素很重要)。

我写了以下几行:

fun foo ([]:(string * int)) = []
  | foo [x] = [x]
  | foo ((x,y)::xs) = 
    let
      val (s,t) = hd(xs) (* gets next element string *)
      fun sort ... = ...
    in

    end

我不知道如何实现sort 函数,但我希望它具有我编写的以下代码:

    case String.compare(x,s) of
      LESS => ...
    | EQUAL => ...
    | GREATER => ...

我还需要在sort 函数中使用val (s,t) = hd(xs),所以它是递归的,但我不确定。此外,我不允许使用任何其他库 - 只能使用隐藏的 let/local。

【问题讨论】:

  • 您不必使用hd(xs)。您可以改用模式匹配。

标签: sml ml


【解决方案1】:

(如果您被允许使用库函数,) SML/NJ 中的ListMergeSort.sort 看起来像:

val sort : ('a * 'a -> bool) -> 'a list -> 'a list

sort f l 返回 l 中的元素列表,按“大于”谓词指定的非降序排序 f。具体来说,如果 f(x,y) 的计算结果为真,那么 x 将出现在结果列表中的 y 之后。

使用这个库函数来写你的foo:

fun foo pairs = ListMergeSort.sort (fn ((s : string,_), (t,_)) => s > t)

如果您使用 SML/NJ 以外的其他编译器,这可能看起来有点不同。


为了解决您的子问题,

我不知道如何实现sort函数

(因为您不允许使用任何库函数,)您可以构建一个以String.compare 作为参数的排序函数。根据排序算法,排序函数的粗略草图可能如下所示:

fun sort cmp [] = []
  | sort cmp [x] = [x]
  | sort cmp xs = ... partially sort xs using `cmp`, combine results ...

它的签名是('a * 'a -> order) -> 'a list -> 'a list

您不是在问如何制作排序功能(只是说您不知道如何),如果您是,我倾向于说这个问题太宽泛了,而您不知道指定您希望实现的算法类型,或者您在此过程中遇到的问题。例如见Rosetta Code's MergeSort,或问答Standard sorting functions in SML?

我希望它具有我编写的以下代码:

case String.compare (x,s) of ...

[...] 我不允许任何其他库 [...]

但是String.compare 也是一个库函数!您可以编写自己的String.compare(a) explode 将字符串分解为字符列表并使用列表递归来确定它们的字典顺序,或者 (b) count 字符串的长度并使用String.sub (s, i) 获取每个字符串的sith 字符,直到确定字典顺序。虽然 (b) 更有效(因为它使用少量且恒定的内存),但 (a) 是列表递归的一个很好的练习。

对于(a),您可以从以下开始:

fun stringCompare (s, t) =
    let fun cmp (x::xs, y::ys) = if x < y then ... else ...
          | cmp (_::_, [])     = ...
          | cmp ([], _::_)     = ...
          | cmp ([], [])       = EQUAL
    in cmp (explode s, explode t) end

然后你可以用同样的方式组合它们:

fun foo pairs = sort (fn ((s,_), (t,_)) => stringCompare (s, t)) pairs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 2023-04-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2022-11-18
    相关资源
    最近更新 更多