在Prolog中查找最长的列表?

在Prolog中查找最长的列表?,prolog,Prolog,我需要编写一个谓词longestList/2,这样如果L2是最长的,那么longestList(L1,L2)就满足了 列表列表L1中的嵌套列表 ?- longestList([[1],[1,2],[1,2,3],[1,2,3,4]],LI). LI = [[1, 2, 3, 4]] ; No ?- longestList([[a,b,c],[d,e],[f,g,h]],LI). LI = [[f, g, h],[a,b,c]]; No 有人能帮我用直觉来解决这个问题吗?member/2可以让你

我需要编写一个谓词longestList/2,这样如果L2是最长的,那么longestList(L1,L2)就满足了 列表列表L1中的嵌套列表

?- longestList([[1],[1,2],[1,2,3],[1,2,3,4]],LI).
LI = [[1, 2, 3, 4]] ;
No
?- longestList([[a,b,c],[d,e],[f,g,h]],LI).
LI = [[f, g, h],[a,b,c]];
No

有人能帮我用直觉来解决这个问题吗?

member/2可以让你从列表中窥视一个元素(你案例的列表):所以,如果你有一个member\u length/3谓词,你可以编写代码

longestList(Lists, Longest) :-
  member_length(Lists, Longest, N),
  \+ ( member_length(Lists, _Another, M), M > N ).

然后,要查找所有最长的,您可以使用findall/3…

这里是一个基本的递归方法的概要。没有@capelical给出的答案那么清晰,但同样简单

我们的想法是遍历列表,并跟踪到目前为止您看到的最长的列表,以及它的长度。然后递归地遍历列表,并在条件指示时更新这些递归参数。这是对用于执行递归“max-list-element”谓词的技术的稍微阐述。为此,您设置了一个包含更多参数(当前最长列表及其长度)的调用

下面是带有新参数的扩展谓词

longestList([L|Ls], LongestListSoFar, GreatestLengthSoFar, LongestList) :-
    % Here, you need to examine L and determine if it should supersede
    %  the longest list so far and its length. You need to keep in mind that
    %  if the length of L is the same as the max length so far, then I
    %  may choose to keep the LongestListSoFar, or choose L. Both are
    %  valid solutions for this call. This is a good place to use the `;`
    %  operator, and to be cautious about parenthesizing expressions since
    %  the comma has higher precedence than the semi-colon.
    %  Also, you'll need to make a recursive call to longestList(Ls, ??, ??, LongestList).
    %  The arguments to the recursion will depend upon which way the decision flow goes.
    %
    % After all that to-do, don't let it scare you: it's about 5 lines of code :)
    %
longestList([], LongestListSoFar, ??, ??).
    % Fill in the ??. What should they be at list's end ([])?
    %   Do I even care now what the 3rd argument is?

希望这足以让你思考如何取得进步。或者,使用@capelical的解决方案并编写
成员长度/3
谓词。:)请注意,正如在他的解决方案中一样,如果存在多个最大回溯列表,则上述解决方案将生成每个最大回溯列表。因此,如果您想在一个列表中获得所有解决方案,可以使用
findall/3

下面的代码使用if-else,似乎部分有效。必须使用0长度调用它,因此不能从这里获取长度本身

longest_list([H|T], LongList, LongLen):-
    length(H, Len),
    (Len > LongLen -> 
        longest_list(T, [H], Len); 
        longest_list(T, LongList, LongLen)).

longest_list([],Finallist,_):-writeln(Finallist).

?- longest_list([[1,2,3], [3,4], [4,5,6,7,8], [5,3,4]], Longestlist, 0).
[[4,5,6,7,8]]
true.
但是,变量本身不会出现:

?- writeln(Longestlist).
_G1955
true.

它可能会提供一些想法。

您应该命名允许使用的功能(阅读库)…我们可以使用长度和附加。这回答了你的问题吗?当然。没有任何限制。只要它容易理解。实际上,我会递归地做这件事,并且有两个累加器。一个是到目前为止看到的当前最大长度,另一个是具有该长度的列表的当前集合。您需要自己尝试一下,并说明具体的困难所在。第一个帮助:
lists\u longestlists/2
是一个关系更为密切的名称。
?- writeln(Longestlist).
_G1955
true.