flatten([A|B],R):- (islist(A)->(flatten(A,R1),R=R1);(write(A),append([A],R1,R))), flatten(B,R1).
flatten(X,X).
islist([_|_]).
Run Code Online (Sandbox Code Playgroud)
这是我写的代码,但我有奇怪的问题..
我明白了
257 ?- flatten([1,[],2,[3],[3,[3,5]]],R).
1[]23335335
R = [1, [], 2, [3], [3, [3, 5]]] .
Run Code Online (Sandbox Code Playgroud)
虽然写入的数字不是列表,但它们作为列表附加:S ...
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).
Run Code Online (Sandbox Code Playgroud)
这里我们使用两个谓词:flatten/2和flatten/3.'work'将在flatten/3中完成,其中第二个参数将保存中间的展平列表.
第一个子句是基本情况:当我们到达空列表时,我们完成了所以我们使用中间展平列表实例化第三个参数.
第二个子句涉及递归.它会使列表中的第一个项目变平(无论是项目还是子列表),然后继续输入列表的其余部分.
最后一个子句是非列表项的"基本案例".它在中间展平列表的开头添加项目,但它仅对非列表的项目执行此操作,因为在第二个子句中小心处理了该情况.