【问题标题】:Get elements from list of lists从列表列表中获取元素
【发布时间】:2012-04-04 08:18:21
【问题描述】:

是否可以从 Prolog 的列表中获取所有元素?

类似:我们有 getElements([[[a,b,[c]],d,e],f,g,[h,[i,j]]],S) 结果是:S = [a,b,c,d,e,f,g,h,i,j] ...

感谢您的帮助。

【问题讨论】:

  • 研究栏+“扁平化”应该会让你开心。

标签: list prolog dcg


【解决方案1】:

您要求列表列表中的所有元素。也就是说,对于[[1,2,3],[4]],这将是列表[1,2,3,4]。但是,对于[[[1],[3]]],这将是列表[[1],[3]],因为[1][3] 是元素。出于这个原因,flatten/2 是不正确的,它给你[1,3] 作为答案。此外,对于1,它会给出[1]...

这是使用的解决方案:

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

seqq([]) --> [].
seqq([Es|Ess]) --> seq(Es), seqq(Ess).

?- phrase(seqq([[[1],[3]]]), Xs).
Xs = [[1],[3]].

?- phrase(seqq(1), Xs).
false.

此解决方案现在也适用于以下情况:

?- phrase(seqq([S1,S2]), [1,2]).
S1 = [],
S2 = [1,2] ;
S1 = [1],
S2 = [2] ;
S1 = [1,2],
S2 = [] ;
false.

flatten/2 完全错误:

?- flatten([S1,S2],[1,2]).
S1 = 1,
S2 = 2.

【讨论】:

    【解决方案2】:

    在 SWI-Prolog(可能还有其他)中,您可以使用 flatten/2

    ?- flatten([[[a,b,[c]],d,e],f,g,[h,[i,j]]], S).
    S = [a, b, c, d, e, f, g, h, i|...].
    

    请注意,the SWI-Prolog manual page for flatten/2 包含以下语句:

    最终需要 flatten/3 通常表明,例如 append/3 用于附加两个列表,这是一个糟糕的设计。

    但是,页面并没有说明是否有另一个原生谓词来替换它。

    我相信会提供更好的答案。

    【讨论】:

    • 好的,谢谢 :) 不知道......虽然我有点希望我能找到诀窍 - 一些算法......但是谢谢;)(对不起我的英语 O:- ))
    • 你可以在这里看到源代码/它是如何实现的。swi-prolog.org/pldoc/doc/swi/library/lists.pl?show=src
    • @magus:此谓词已弃用。请阅读您提到的来源中的理由:最终需要 flatten/3 通常表明,例如 append/3 用于附加两个列表,这是一个糟糕的设计。从生成的小列表生成列表的高效代码必须使用差异列表,通常可以通过语法规则实现最佳可读性。
    猜你喜欢
    • 2014-12-16
    • 1970-01-01
    • 2022-07-09
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多