我是Prolog的新手,我很难弄清楚如何在列表中找到包含数字和字母的第二个最小值。当它包含一个字母时,它应该显示一个错误,当它有一个数字时,它应该显示一个错误。到目前为止,我有这个,但我不知道如何开始我的代码有信......
secondMin([_]) :-
print("ERROR: List has fewer than two unique elements."),
!.
secondMin(List, M2) :-
min_list(List, M1),
delete(List, M1, List1),
min_list(List1, M2).
输出应如下所示:
?- secondMin([17,29,11,62,37,53], M2).
M2 = 17
?- secondMin([512], M2).
ERROR: List has fewer than two unique elements.
?- secondMin([7,5.2,3,6,-3.6,9,-2], M2).
M2 = -2
?- secondMin([12,2,b,7], M2).
ERROR: "b" is not a number.
?- secondMin([3,3,3], M2).
ERROR: List has fewer than two unique elements.
答案 0 :(得分:0)
最简单但最迫切的方法是使用maplist
来确定是否存在任何非数字。然后使用sort
获取唯一的第二分钟。
secondMin(L, M) :-
( maplist(number, L)
-> ( sort(L, [_,Second|_])
-> M = Second
; print("List has fewer than two unique elements.")
)
; print("List has non-numeric elements")
).
<小时/> 正如@repeat在他的评论中所指出的,上述解决方案是“天真的”#34;从某种意义上说,虽然它为有效输入产生了正确的结果,但除了显示诊断消息之外,它没有适当的错误处理,但随后成功。
这是一个更全面的实现,当第一个参数没有按预期定义时,它会引发异常:
secondMin(L, M) :-
( ground(L)
-> ( is_list(L),
maplist(number, L)
-> ( sort(L, [_,Second|_])
-> M = Second
; throw('List has fewer than two unique elements')
)
; throw('First argument is not a list of numbers')
)
; throw(error(instantiation_error, _))
).