【问题标题】:Filter the numeric elements based on target value in Prolog根据 Prolog 中的目标值过滤数字元素
【发布时间】:2021-12-13 10:47:53
【问题描述】:
public class Filter {

  public static List<Number> apply(List<Number> lst, Double target){

    return lst.stream()
            .mapToDouble( Number::doubleValue )
            .filter( elem -> elem > target )
            .boxed()
            .collect( Collectors.toCollection(ArrayList::new ));
    }
    public static void main(String[] args) {

//    Integer[] nums = new Integer[] {1,2,3,4,5,6,7,8,9};

      Double[] nums = new Double[] {2.1,3.2,4.3,5.4,6.5,7.6,8.7};

      System.out.println(Filter.apply( Arrays.asList(nums), 5.0 ) 
      );
    }
}

【问题讨论】:

  • 你想从你的代码中得到什么?
  • 我想要一个大于给定数字的数字,例如双数组中大于 5.0 的所有数字
  • 或者简而言之我想把这个java应用方法转换成PROLOG
  • Umar:这就是你的程序正在做的事情,它会返回所有大于 5.0 的上限值 [5.4, 6.5, 7.6, 8.7]
  • 是的,我需要 PROLOG 语言

标签: arrays list sorting filter prolog


【解决方案1】:

记住 split/3 和 merge/3 是“帮助谓词”:

split([X], [], [X]).

split([H1, H2 | List], [H1 | ListA], [H2 | Result]) :-
    split(List, ListA, Result).

merge([], L, L).
merge(L, [], L).

merge([H1 | List], [H2 | ListA], [H1 | Result]) :-
    H1 < H2,
    !,
    merge(List, [H2 | ListA], Result).

merge(List, [H2 | ListA], [H2 | Result]) :-
    merge(List, ListA, Result).


merge_sort([], []).
merge_sort([A], [A]).

merge_sort(List, SList):-
  split(List, List1, List2),
  merge_sort(List1, SList1),
  merge_sort(List2, SList2),
  merge(SList1, SList2, SList).

如果你查询,你应该得到这个:

?- split([2, 5, 7, 4, 3, 1, 9, 8, 6], ListA, ListB).
ListA = [2, 7, 3, 9],
ListB = [5, 4, 1, 8, 6] .

?- merge([1, 3, 5, 7, 9], [2, 4, 6, 8], MergedList).
MergedList = [1, 2, 3, 4, 5, 6, 7, 8, 9] .

?- merge_sort([2, 5, 7, 4, 3, 1, 9, 8, 6], Result).
Result= [1, 2, 3, 4, 5, 6, 7, 8, 9].

【讨论】:

  • #Hyakkimaru 我不需要排序我需要从 PROLOG 中的数组中的目标数中获取所有大数
【解决方案2】:

这样的事情会起作用:

%---------------------------
% find all Xs greater than Y
%---------------------------
items_greater_than( []     , _ , []    ) .
items_greater_than( [X|Xs] , Y , [X|Zs ) :- X @>  Y, items_greater_than(Xs,Y,Zs).
items_greater_than( [X|Xs] , Y , Zs    ) :- X @=< Y, items_greater_than(Xs,Y,Zs).

执行

items_greater_than( [2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7], 5.0, R ).

应该让步

R = [ 5.4, 6.5, 7.6, 8.7 ]

【讨论】:

  • s(X) 用于谓词名称!谢谢!
【解决方案3】:

类似于 Java 的filter 是来自库的include/3(apply),而库(yall) 为我们提供匿名谓词,类似于arrow functions

items_greater_than(Items,Value,ItemsGreater) :-
  include({Value}/[I]>>(I>Value),Items,ItemsGreater).

如果您的 Prolog 缺少上述任何一个库,这可能会起作用:

items_greater_than(Items,Value,ItemsGreater) :-
  findall(I,(member(I,Items),I>Value),ItemsGreater).

请记住,在 Prolog 中我们没有函数,而是谓词。

编辑

感谢@TA_intern 的明智评论,这是一个不需要 library(yall) 的解决方案:

items_greater_than(Items,Value,ItemsGreater) :-
  include(<(Value),Items,ItemsGreater).

由于 library(apply) 将列表项附加到谓词的参数末尾,因此我们使用 (<)/2 谓词而不是 (>)/2

【讨论】:

  • 我不想投反对票,但 lambda 确实没有必要。您可以直接调用它,include(&lt;(5.0), ...) 或使用 compare/3,例如 include(compare(&lt;, 5.0), ...)
  • @TA_intern:你说得对,我的错。将修改我的答案。
  • @TA_intern:完成了,但我认为 lambda 库使用的简单实用示例具有一定的教学价值。因此,我将保留基于库(yall)的解决方案。
【解决方案4】:

如果您使用的是 SWI-Prolog,您将使用 include/3,如下所示:

?- include(<(5.0), [2.1,3.2,4.3,5.4,6.5,7.6,8.7], R).
R = [5.4, 6.5, 7.6, 8.7].

这与 Java 代码完全相同:它接受一个列表,对每个元素应用一个谓词,并且只收集谓词成功的元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多