消光列表(Flatting a list)

2019-09-18 14:02发布

我需要编写一个函数,平坦的列表。

例如:

flat([ c , [[[]]] , [] , k] , X).
X=[c,k]

这是我做的:

    flat([],[]).
    flat([[A] |B] , R) :- flat([A|B],R).
    flat([[]|L],L1) :- flat(L,L1).!
    flat([[A|L]|W],R) :- flat([A|L],U), flat(W,W1), append(U,W1,R).
    flat([A|L], [A|L1]) :- flat(L,L1).

我知道为什么这是不正确的,但我不知道该怎么做。 谢谢。

编辑:几乎工作:

    flat([],[]).
flat([[]|L],L1) :- flat(L,L1).  --- i think something here missing
flat([[A|L]|W],R) :- flat([A|L],U), flat(W,W1), append(U,W1,R).
flat([A|L], [A|L1]) :- flat(L,L1).


?- flat([c , [[[]]] , [] , k],C).
C = [c, k] ;
C = [c, [], k] ;
C = [c, [], k] ;
C = [c, [], [], k] ;
C = [c, [[]], k] ;
C = [c, [[]], [], k] ;
C = [c, [[[]]], k] ;
C = [c, [[[]]], [], k].

Answer 1:

flatten(List, FlatList) :-
    flatten(List, [], FlatList0), !,
    FlatList = FlatList0.

flatten(Var, Tl, [Var|Tl]) :-
    var(Var), !.
flatten([], Tl, Tl) :- !.
flatten([Hd|Tl], Tail, List) :- !,
    flatten(Hd, FlatHeadTail, List),
    flatten(Tl, Tail, FlatHeadTail).
flatten(NonList, Tl, [NonList|Tl]).

这里是由Jan Wielemaker和理查德·奥基夫SWI-Prolog的解决方案,代码可以在序言的图书馆目录可以发现,lists.pl文件。



Answer 2:

代码编辑(见注释)

另一个possibiliy,采用DCG:

flat(L, FL) :-
    flat(L, FL, []).

flat(X) -->
    {var(X)},
    !,
    [X].

flat([]) --> 
    [], 
    !.

flat([X | T]) -->
    flat(X),
    !,
    flat(T).

flat(X) --> [X].

现在,我们得到:

 ?- flat([[a,b,c,d|r]], FL) .
FL = [a,b,c,d,r] .


 ?- flat([1,2,[3,4]],L).
L = [1,2,3,4] .

 ?- flat([1,2,[3,4]],[1,2,3,4]).
true .

 ?- flat([ c , [[[]]] , [] , k] , X).
X = [c,k] .


Answer 3:

那邦(...平(L,L1)。!...)这是一个错字,是不是?

你可以学习好的执行从SWI-Prolog的,暴露其代码并给出了什么样的预期:

?- flatten([ c , [[[]]] , [] , k] , X).
X = [c, k].

否则,尝试用一个简单的例子来调试,看看你的代码,清洗一次,失败。 顺便说一句,你的代码似乎工作,只是得到更多的解决方案,你需要修剪一些不需要的路径:

?- flat([c , [[[]]] , [] , k],C).
C = [c, k] ;
C = [c, [], k] ;
C = [c, [], k] ;
C = [c, [], [], k] .
...

编辑这里是SWI-Prolog的从库(名单)代码

%%  flatten(+List1, ?List2) is det.
%
%   Is true if List2 is a non-nested version of List1.
%
%   @deprecated Ending up needing flatten/3 often indicates,
%           like append/3 for appending two lists, a bad
%           design.  Efficient code that generates lists
%           from generated small lists must use difference
%           lists, often possible through grammar rules for
%           optimal readability.
%   @see append/2

flatten(List, FlatList) :-
    flatten(List, [], FlatList0), !,
    FlatList = FlatList0.

flatten(Var, Tl, [Var|Tl]) :-
    var(Var), !.
flatten([], Tl, Tl) :- !.
flatten([Hd|Tl], Tail, List) :- !,
    flatten(Hd, FlatHeadTail, List),
    flatten(Tl, Tail, FlatHeadTail).
flatten(NonList, Tl, [NonList|Tl]).

您的代码似乎相当正确WRT您的评论:

?- flat([1,2,[3,4]],[1,2,3,4]).
true ;
false.


文章来源: Flatting a list
标签: prolog dcg