Prolog展平列表

时间:2011-06-17 09:18:46

标签: prolog

flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1).
    flatten(X,X).
    islist([_|_]).

这是我写的代码,但我有一个奇怪的问题..

我得到了

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

虽然写入的数字不是列表,但它们作为列表附加:S ...

1 个答案:

答案 0 :(得分:7)

您对flatten / 2的定义中存在一些错误:

你的第一个子句将失败,因为如果A是一个列表,它将首先用R实例化R1,然后你尝试用flatten(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).

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

第一个子句是基本情况:当我们到达空列表时,我们就完成了,所以我们用中间的扁平列表实例化第三个参数。

第二个句子涉及递归。它会使列表中的第一个项目变平(无论是项目还是子列表),然后继续输入列表的其余部分。

最后一个子句是非列表项的“基本案例”。它在中间展平列表的开头添加了该项目,但它仅针对非列表的项目执行此操作,因为在第二个子句中已采用该情况。

相关问题