Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 如何在列表列表中找到最长的列表?_List_Prolog_Meta Predicate - Fatal编程技术网

List 如何在列表列表中找到最长的列表?

List 如何在列表列表中找到最长的列表?,list,prolog,meta-predicate,List,Prolog,Meta Predicate,我有一个列表,我需要找到其中最长的一个。如果有多个具有相同长度的,则返回的长度相同。谢谢。这里有一个通用谓词,它扫描列表以查找由给定目标定义的单个成员 select_element(Goal, [Head | Tail], Selected) :- select_element(Goal, Tail, Head, Selected). select_element(_Goal, [], Selected, Selected). select_element(Goal, [Head

我有一个列表,我需要找到其中最长的一个。如果有多个具有相同长度的,则返回的长度相同。谢谢。

这里有一个通用谓词,它扫描列表以查找由给定目标定义的单个成员

select_element(Goal, [Head | Tail], Selected) :-
    select_element(Goal, Tail, Head, Selected).


select_element(_Goal, [], Selected, Selected).

select_element(Goal, [Head | Tail], Current, FinalSelected) :-
    call(Goal, Head, Current, Selected),
    select_element(Goal, Tail, Selected, FinalSelected).
假设您定义了一个谓词

get_bigger_number(N1, N2, N) :-
    N is max(N1, N2).
现在您可以执行:

?- select_element(get_bigger_number, [5, 1, -2, 10, 3.2, 0], Selected).

Selected = 10
所以你现在需要做的就是定义一个谓词
get\u longer\u list(L1,L2,L)
, 并使用它而不是
获取更大的数字/3


当然,使用像
select\u element/3
这样的通用谓词可能效率不高。例如,您应该尽量避免多次计算同一列表的长度,因为这个计算在Prolog中是慢的(至少如果以标准的方式在Prolog中实现)。
longest([L], L) :-
   !.
longest([H|T], H) :- 
   length(H, N),
   longest(T, X),
   length(X, M),
   N > M,
   !.
longest([H|T], X) :-
   longest(T, X),
   !.
然后你可以查阅:

?- longest([[1]], N).
N = [1] ;

?- longest([[1],[2]], N).
N = [2] .

?- longest([[1],[2], [3,3,3], [2]], N).
N = [3, 3, 3] ;

?- longest([[1],[2], [3,3,3], [2]], N).
N = [3, 3, 3].

?- longest([[1],[2], [3,3,3], [2], [4,4,4,4]], N).
N = [4, 4, 4, 4] .

?- longest([[1],[2], [3,3,3], [2], [4,4,4,4]], N).
N = [4, 4, 4, 4] ;

欢迎

要获得最长列表的长度:

%sample: longest([[2,1,3],[7,5],[1,8,2,3,1],[2,7,1,4]],L,LEN).

longest([L], L, _) :-
   !.
longest([H|T], H, _) :-
   length(H, N),
   longest(T, X, N),
   length(X, M),
   N > M,
   !.
longest([_|T], X, LEN) :-
   length(X, LEN),
   longest(T, X, LEN),
   !.

我们根据与以下内容结合使用的方式定义
最长/2

示例查询:

?- longest([[1],[2]],Xs).      % we expect   multiple solutions
  Xs = [1]                
; Xs = [2].                    % we    _get_ multiple solutions

?- longest([[2,1,3],[7,5],[1,8,2,3,1],[2,7,1,4]],Xs).
Xs = [1,8,2,3,1].              % succeeds deterministically

这是另一种有效且易于理解的方法。其思想是找到列表中所有列表的长度,使用
max\u list
获得最长列表的长度,然后找到一个那么长的列表。这样做的好处是它将返回所有长度最长的列表

lengths([],[]).
lengths([H|T], [LH|LengthsT]) :-
    length(H, LH),
    lengths(T, LengthsT).

lengthLongest(ListOfLists, Max) :-
    lengths(ListOfLists, Lengths),
    max_list(Lengths, Max).

longestList(ListOfLists, Longest) :-
    lengthLongest(ListOfLists, Len),
    member(Longest, ListOfLists),
    length(Longest, Len).

你能写一个三位谓词来比较两个列表并“返回”较长的列表吗?嗯,也许吧。我待会再看。现在我有一个讲座。我不知道如果这个数字是实际的列表,会是什么样。因为列表的头是一个列表。select_元素/3不关心列表元素的性质(例如原子或列表)。一切都取决于您必须编写的谓词(get_longer_list/3)。当然,您也可以验证被操纵的对象实际上是列表。解决方案的复杂性为O(n^2)。这对于这样一个简单的问题来说太难了……目标
最长([[1],[2]],[1])
失败了。它应该成功!s(X)用于返回最大长度的所有列表。
?- longest([[1],[2]],Xs).      % we expect   multiple solutions
  Xs = [1]                
; Xs = [2].                    % we    _get_ multiple solutions

?- longest([[2,1,3],[7,5],[1,8,2,3,1],[2,7,1,4]],Xs).
Xs = [1,8,2,3,1].              % succeeds deterministically
lengths([],[]).
lengths([H|T], [LH|LengthsT]) :-
    length(H, LH),
    lengths(T, LengthsT).

lengthLongest(ListOfLists, Max) :-
    lengths(ListOfLists, Lengths),
    max_list(Lengths, Max).

longestList(ListOfLists, Longest) :-
    lengthLongest(ListOfLists, Len),
    member(Longest, ListOfLists),
    length(Longest, Len).