此函数查找列表的最大数量,并且我很难理解它:
fun max1 (xs : int list) =
if null xs
then NONE
else
let val tl_ans = max1(tl xs)
in
if isSome tl_ans andalso valOf tl_ans > hd xs
then
tl_ans
else
SOME (hd xs)
end;
如何在行tl_ans
中计算if isSome tl_ans andalso valOf tl_ans > hd xs
既然还没有设定呢?
答案 0 :(得分:2)
该功能有两种情况:
1)基础案例 - 列表为空
没有最大值,返回NONE
2)List不为空 - 由于列表不为空,列表将有一个头(第一个元素)和一个尾(除第一个之外的所有元素)。请注意,对于包含一个元素的列表,尾部将为空。
这里的想法是,对于非空列表,在函数中递归计算列表尾部的最大值,tl_ans
(尾部答案或尾部最大值)。由于我们知道除了第一个元素(头部)之外的所有元素中的最大值,现在整个列表的最大值只是tl_ans
和列表头部中的最大值。
在每次递归调用时,输入大小减1,因为我们只是传递列表的尾部(即没有第一个元素)。当它只有一个尾部为空的元素的列表时,这将最终调用基本情况。从那里开始,在每次递归调用的回程中,递归调用的头部将与递归返回的内容进行比较。
以下是插图:
最大[5,2,6,4]
tl_ans = max [2,6,4], hd = 5
|
|=>tl_ans = max [6,4], hd = 2
|
|=>tl_ans = max [4], hd = 6
|
|=>tl_ans = max [], hd = 4
|
|<= None (Base case)
<= Some 4, comparing tl_ans (None) and hd (4)
<== Some 6, comparing tl_ans (Some 4) and hd (6)
<= Some 6, comparing tl_ans (Some 6) and hd (2)
<= Some 6, comparing tl_ans (some 6) and hd (5)
答案 1 :(得分:2)
这不是在标准ML中编写此类函数的最惯用的方法。我建议,以另一种方式写它将更好地理解它是如何工作的。函数valOf
,hd
和tl
是所谓的partial functions,使用它们的唯一理由是确保其输入不是NONE
或{分别为{1}}(在这种情况下,程序将调用异常)。
使用[]
,valOf
或hd
将要求您检查列表是否为空(例如tail
)或存在选项(例如{{1} }),因此使用它的便利性是有限的。相反,需要使用模式匹配(或这些函数的更多健壮版本)。
下面我以其他两种方式编写了相同的功能,其中一种类似于你提供的功能。
null xs
答案 2 :(得分:1)
行
let val tl_ans = max1(tl xs)
in
if isSome tl_ans andalso valOf tl_ans > hd xs
在以下代码中让 tl_ans
为max1 (tl xs)
的值。
(您通常会说max1 (tl xs)
的值绑定到名称(或变量)“tl_ans”。)
与
完全相同if isSome (max1 (tl xs)) andalso valOf (max1 (tl xs)) > hd xs
除了值max1 (tl xs)
仅计算一次。