打印列表中最大数字的长度时出现 SML 错误
SML error in printing off length of largest number in a list
我正在使用 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;
样本input/output
- 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?
maxL 是 return 数位,但其 return 值用作 max 的第二个参数,将该值与列表头部的值进行比较。由于列表中没有数字超过 4 位,因此取 5 为准,它有 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
计算的是数字的位数,而不是列表的最大数字的数字,所以你不能真正使用 maxL
产生的结果作为 max
.
的参数
I'm using 3 functions to find the largest number in a list and print its length.
通过更简单的步骤分解您的目标:
- 找出列表中最大的数字
- 并打印它的长度
您可能已经明白这不是您在做的事情。您的算法执行以下操作:
- 在第一个元素和尾列表中分解一个列表
- 获取所述第一个元素和
maxL(tail)
之间的最大值
- 计算该最大值的数字长度
如果将内部调用扩展到 maxL
,区别就会变得很明显:
- 在第一个元素和尾列表中分解一个列表
- 在第二个元素和第二个尾列表中分解尾列表
- 获取所述第二个元素与
maxL(second tail)
之间的最大值
- 计算第一个最大值的数字长度
- 获取所述第一个元素与前一个最大值的数字长度之间的最大值
- 计算该最大值的数字长度
为了修复算法,您需要将对 num_digits
的调用从递归中拉出,然后按照您最初陈述的目标应用它。
我正在使用 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;
样本input/output
- 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?
maxL 是 return 数位,但其 return 值用作 max 的第二个参数,将该值与列表头部的值进行比较。由于列表中没有数字超过 4 位,因此取 5 为准,它有 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
计算的是数字的位数,而不是列表的最大数字的数字,所以你不能真正使用 maxL
产生的结果作为 max
.
I'm using 3 functions to find the largest number in a list and print its length.
通过更简单的步骤分解您的目标:
- 找出列表中最大的数字
- 并打印它的长度
您可能已经明白这不是您在做的事情。您的算法执行以下操作:
- 在第一个元素和尾列表中分解一个列表
- 获取所述第一个元素和
maxL(tail)
之间的最大值
- 计算该最大值的数字长度
如果将内部调用扩展到 maxL
,区别就会变得很明显:
- 在第一个元素和尾列表中分解一个列表
- 在第二个元素和第二个尾列表中分解尾列表
- 获取所述第二个元素与
maxL(second tail)
之间的最大值
- 计算第一个最大值的数字长度
- 获取所述第一个元素与前一个最大值的数字长度之间的最大值
- 计算该最大值的数字长度
为了修复算法,您需要将对 num_digits
的调用从递归中拉出,然后按照您最初陈述的目标应用它。