我使用3个函数查找列表中的最大数字并打印它的长度。
样本输入为maxL [5,199,3000,63];
fun max(a,b) =
if
a>b
then
a
else
b;
fun maxL(L) =
if L=[] then
0
else
let
val largest = max(hd(L), maxL(tl(L)))
in
num_digits largest
end;
fun num_digits 0 = 0
|num_digits 1 = 1
| num_digits x = num_digits(x div 10) + 1;
示例输入/输出
- maxL [5, 199, 3000, 63];
val it = 1 : int
在这里,我将程序修改为只打印最大,以验证它是否找到了最大的
- use "hw4.sml";
[opening hw4.sml]
val num_digits = fn : int -> int
val max_digits = fn : int list -> int
val max = fn : int * int -> int
val maxL = fn : int list -> int
val it = () : unit
- maxL [5, 199, 3000, 63];
val it = 3000 : int
在这里,我测试的是3000或者最大的,实际上正在打印出正确的长度。
- num_digits 3000;
val it = 4 : int
我的问题是:为什么我打电话给num_digits largest
时打印1,但如果我打电话给num_digits 3000
打印4?
答案 0 :(得分:1)
maxL返回多个数字,但其返回值用作max的第二个参数,将该值与列表头部的值进行比较。由于列表中的数字不超过4位数,因此值为5,并且有1位数。因此输出。
答案 1 :(得分:1)
尝试手动减少表达式:
maxL [5, 199, 3000, 63];
=> num_digits (max (5, maxL [199, 3000, 63]))
=> num_digits (max (5, num_digits (max (199, maxL [3000, 63]))))
=> num_digits (max (5, num_digits (max (199, num_digits (max (3000, maxL [63]))))))
=> num_digits (max (5, num_digits (max (199, num_digits (max (3000, num_digits (max (63, maxL []))))))))
=> num_digits (max (5, num_digits (max (199, num_digits (max (3000, num_digits (max (63, 0))))))))
=> num_digits (max (5, num_digits (max (199, num_digits (max (3000, num_digits 63))))))
=> num_digits (max (5, num_digits (max (199, num_digits (max (3000, 2))))))
=> num_digits (max (5, num_digits (max (199, num_digits 3000))))
=> num_digits (max (5, num_digits (max (199, 4))))
=> num_digits (max (5, num_digits 199))
=> num_digits (max (5, 3))
=> num_digits 5
1
简而言之,maxL
正在计算数字的位数,而不是数字列表中最大数,因此您可以&#39 ; t确实使用maxL
生成的结果作为max
的参数。
答案 2 :(得分:0)
我正在使用3个函数来查找列表中的最大数字并打印其长度。
以更简单的步骤分解您的目标:
您可能已经看到这不是您正在做的事情。您的算法执行以下操作:
maxL(tail)
如果将内部呼叫扩展为maxL
,则差异变得明显:
maxL(second tail)
为了修复算法,您需要将调用从num_digits
拉出递归,然后按原定的目标应用它。