繁体   English   中英

SWI-Prolog:在列表中找到第二个最小值

[英]SWI-Prolog: finding the second minimum in a list

我是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.

最简单但最迫切的方法是使用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在他的评论中指出的那样,上述解决方案在某种意义上是“天真的”,尽管它为有效输入产生了正确的结果,但除了显示诊断消息之外,它没有适当的错误处理。成功。

这是一个更彻底的实现,当第一个参数没有按预期定义时,它会引发异常:

 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, _)) ). 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM