按字典顺序排列元组列表

时间:2018-05-14 10:58:42

标签: sml ml

我试图在Standard 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 => ...

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

1 个答案:

答案 0 :(得分:0)

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

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

sort f l 返回 l 中的元素列表,按照``大于&#指定的非递减顺序排序39;'谓词 f 。具体来说,如果 f(x,y) 评估为true,那么 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或Q& A Standard sorting functions in SML?

  

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

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

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

但是String.compare也是一个库函数!你可以自己编写String.compare(a) 将字符串分解为字符列表并使用列表递归来确定字典顺序,或者(b) count < / em>字符串的长度,并使用String.sub (s, i)为每个字符串获取 i s 字符,直到字典顺序是确定的。虽然(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