我试图在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。
答案 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