2012-03-19 84 views
3

是否可以从Prolog列表中获取列表中的所有元素?我们有getElements([[[a,b,[c]],d,e],f,g,[h,[i,j]]],S),结果如下: S = [a,b,c,d,e,f,g,h,i,j] ...从列表中获取元素

感谢您的帮助。

+0

研究栏+“flatten”应该让你开心。 – m09 2012-03-19 20:24:11

回答

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包括以下语句:

结束了需要压平/ 3经常表示,像追加/ 3追加两个列表,一个糟糕的设计。

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

我相信会有更好的答案。

+0

好的谢谢:)没有知道它...虽然我希望有一点,我会找出诀窍 - 一些算法......但谢谢;)(和对不起,我的英语O :-)) – kolage 2012-03-19 20:29:12

+1

你可以看到来源/它是如何在这里实现的。http://www.swi-prolog.org/pldoc/doc/swi/library/lists.pl?show=src – magus 2012-03-19 22:18:30

+3

@magus:这个谓词已被弃用。请在您提到的源代码中阅读它的理由:结束需要拼合/ 3通常表示, 像追加/ 3用于追加两个列表,一个不好的 设计。从生成的小列表生成列表 的高效代码必须使用差异 列表,通常可以通过文法规则获得最佳可读性。 – false 2012-03-20 10:00:09

3

您询问了列表的所有元素。也就是说,对于[[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.