2011-06-17 89 views
4
flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1). 
    flatten(X,X). 
    islist([_|_]). 

这是我写的代码,但我有奇怪的问题..Prolog的扁平化列表

我得到

257 ?- flatten([1,[],2,[3],[3,[3,5]]],R). 
1[]23335335 
R = [1, [], 2, [3], [3, [3, 5]]] . 

虽然从写没有列出他们被追加为列表中的号码:S ...

+0

请改善您的代码的格式。事实上,这是不可能读的。 – Kaarel 2011-06-17 12:17:26

+1

+1。不知道为什么有人给这个问题-1。有示例代码和输出表明不需要的行为。 – z5h 2011-06-20 15:37:34

回答

7

,我们在您的定义一些错误压扁/ 2:

你第一句话会失败是因为如果A是一个列表,它将首先用R实例化R1,然后尝试用平坦化(B,R1)再次统​​一它。

变平(X,X)。 - >这个条款将'原样'留在列表中,没有任何压缩。

检查这个其他实施:

flatten(List, Flattened):- 
    flatten(List, [], Flattened). 

flatten([], Flattened, Flattened). 
flatten([Item|Tail], L, Flattened):- 
    flatten(Item, L1, Flattened), 
    flatten(Tail, L, L1). 
flatten(Item, Flattened, [Item|Flattened]):- 
    \+ is_list(Item). 

这里我们使用两个谓词:压平/ 2和压平/ 3。 'work'将在flatten/3中完成,其中第二个参数将保存中间平展列表。

第一子句是基本情形:当我们到达空列表,我们这样做我们实例与中间扁平列表中的第三个参数。

第二个子句处理递归。它将列表中的第一个项目弄平(无论是项目还是子列表),并继续处理输入列表的其余部分。

最后一项是非列表项的“基本情况”。它预先考虑在中间压平列表的开头的项目,但它只做这是在不列为该案件的第二子句中的照顾项目。

+1

感谢你的explanation.i曾1天序言​​经验..这是一个有点怪异:) – GorillaApe 2011-06-20 16:04:18