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 ...
答案 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中完成,其中第二个参数将保存中间的展平列表。
第一个子句是基本情况:当我们到达空列表时,我们就完成了,所以我们用中间的扁平列表实例化第三个参数。
第二个句子涉及递归。它会使列表中的第一个项目变平(无论是项目还是子列表),然后继续输入列表的其余部分。
最后一个子句是非列表项的“基本案例”。它在中间展平列表的开头添加了该项目,但它仅针对非列表的项目执行此操作,因为在第二个子句中已采用该情况。