列表中的数字小于给定数字

编程入门 行业动态 更新时间:2024-10-24 22:29:46
本文介绍了列表中的数字小于给定数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 xMenores(_,[],[]). xMenores(X,[H|T],[R|Z]) :- xMenores(X,T,Z), X > H, R is H.

xMenores带有三个参数:

  • 第一个是数字.
  • 第二个是数字列表.
  • 第三个是列表,并且是将包含结果的变量.

规则xMenores的目标是获得一个列表,该列表的编号(第二个参数)小于第一个参数上的值.例如:

The objective of the rule xMenores is obtain a list with the numbers of the list (Second parameter) that are smaller than the value on the first parameter. For example:

?- xMenores(3,[1,2,3],X). X = [1,2]. % expected result

问题在于,当X > H为false并且我的编程技能在序言中几乎为空时,xMenores返回false.所以:

The problem is that xMenores returns false when X > H is false and my programming skills are almost null at prolog. So:

?- xMenores(4,[1,2,3],X). X = [1,2,3]. % Perfect. ?- xMenores(2,[1,2,3],X). false. % Wrong! "X = [1]" would be perfect.

我考虑使用X > H, R is H.是因为我需要每当X大于H时,R就采用H的值.但是我不知道像Prolog中的if或类似的控件结构可以处理此问题.

I consider X > H, R is H. because I need that whenever X is bigger than H, R takes the value of H. But I don't know a control structure like an if or something in Prolog to handle this.

请问有什么解决办法吗?谢谢.

Please, any solution? Thanks.

推荐答案

使用( if -> then ; else )

您可能要寻找的控制结构是( if -> then ; else ).

警告:您可能应该交换前两个参数的顺序:

Warning: you should probably swap the order of the first two arguments:

lessthan_if([], _, []). lessthan_if([X|Xs], Y, Zs) :- ( X < Y -> Zs = [X|Zs1] ; Zs = Zs1 ), lessthan_if(Xs, Y, Zs1).

但是,如果您正在编写真实代码,则几乎可以肯定应该使用库(应用),例如include/3,如由@CapelliC建议:

However, if you are writing real code, you should almost certainly go with one of the predicates in library(apply), for example include/3, as suggested by @CapelliC:

?- include(>(3), [1,2,3], R). R = [1, 2]. ?- include(>(4), [1,2,3], R). R = [1, 2, 3]. ?- include(<(2), [1,2,3], R). R = [3].

请参见 include/3 的实现.您会注意到上面的lessthan/3只是库(应用)中更通用的include/3的特化:include/3将重新排列参数并使用( if -> then ; else ).

See the implementation of include/3 if you want to know how this kind of problems are solved. You will notice that lessthan/3 above is nothing but a specialization of the more general include/3 in library(apply): include/3 will reorder the arguments and use the ( if -> then ; else ).

或者,较少程序性"而较多声明性"的谓词:

Alternatively, a less "procedural" and more "declarative" predicate:

lessthan_decl([], _, []). lessthan_decl([X|Xs], Y, [X|Zs]) :- X < Y, lessthan_decl(Xs, Y, Zs). lessthan_decl([X|Xs], Y, Zs) :- X >= Y, lessthan_decl(Xs, Y, Zs).

(lessthan_if/3和lessthan_decl/3与Nicholas Carey的解决方案几乎相同,除了顺序争论.)

(lessthan_if/3 and lessthan_decl/3 are nearly identical to the solutions by Nicholas Carey, except for the order of arguments.)

不利的一面是,lessthan_decl/3留下了选择点.但是,对于一般的可读解决方案来说,这是一个很好的起点.我们需要两个代码转换:

On the downside, lessthan_decl/3 leaves behind choice points. However, it is a good starting point for a general, readable solution. We need two code transformations:

  • 用CLP(FD)约束替换算术比较<和>=:#<和#>=;
  • 使用DCG规则消除定义中的参数.
  • Replace the arithmetic comparisons < and >= with CLP(FD) constraints: #< and #>=;
  • Use a DCG rule to get rid of arguments in the definition.
  • 您将通过lurker到达解决方案.

    You will arrive at the solution by lurker.

    Prolog中最通用的比较谓词是 compare/3 .一种使用它的常见模式是显式枚举Order的三个可能值:

    The most general comparison predicate in Prolog is compare/3. A common pattern using it is to explicitly enumerate the three possible values for Order:

    lessthan_compare([], _, []). lessthan_compare([H|T], X, R) :- compare(Order, H, X), lessthan_compare_1(Order, H, T, X, R). lessthan_compare_1(<, H, T, X, [H|R]) :- lessthan_compare(T, X, R). lessthan_compare_1(=, _, T, X, R) :- lessthan_compare(T, X, R). lessthan_compare_1(>, _, T, X, R) :- lessthan_compare(T, X, R).

    (与其他解决方案相比,该解决方案可以使用任何术语,而不仅仅是整数或算术表达式.)

    (Compared to any of the other solutions, this one would work with any terms, not just integers or arithmetic expressions.)

    将compare/3替换为 zcompare/3 :

    :- use_module(library(clpfd)). lessthan_clpfd([], _, []). lessthan_clpfd([H|T], X, R) :- zcompare(ZOrder, H, X), lessthan_clpfd_1(ZOrder, H, T, X, R). lessthan_clpfd_1(<, H, T, X, [H|R]) :- lessthan_clpfd(T, X, R). lessthan_clpfd_1(=, _, T, X, R) :- lessthan_clpfd(T, X, R). lessthan_clpfd_1(>, _, T, X, R) :- lessthan_clpfd(T, X, R).

    这肯定比其他任何解决方案都要多的代码,但它不会留下不必要的选择点:

    This is definitely more code than any of the other solutions, but it does not leave behind unnecessary choice points:

    ?- lessthan_clpfd(3, [1,3,2], Xs). Xs = [1, 2]. % no dangling choice points!

    在其他情况下,其行为与潜伏者的DCG解决方案一样:

    In the other cases, it behaves just as the DCG solution by lurker:

    ?- lessthan_clpfd(X, [1,3,2], Xs). Xs = [1, 3, 2], X in 4..sup ; X = 3, Xs = [1, 2] ; X = 2, Xs = [1] ; X = 1, Xs = [] . ?- lessthan_clpfd(X, [1,3,2], Xs), X = 3. % X = 3, Xs = [1, 2] ; % no error! false. ?- lessthan_clpfd([1,3,2], X, R), R = [1, 2]. X = 3, R = [1, 2] ; false.

    除非您需要这种通用方法,否则include(>(X), List, Result)就足够了.

    Unless you need such a general approach, include(>(X), List, Result) is good enough.

    更多推荐

    列表中的数字小于给定数字

    本文发布于:2023-11-30 21:28:39,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1651525.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:数字   列表中

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!