我在另一篇关于如何将树更改为列表的帖子中尝试了某人的评论建议。但是,我在某处(或某事)有一个未声明的变量,所以我的列表中的值是[_G667,_G673,_G679],而不是[5,2,6],这是正确的答案。据我所知,所有的操作都是正确的。
以下是代码:
flatten( Item , []).
flatten( tree(Left, Val, Right), List) :-
flatten(Left, List1),
append(List1, [E], List2),
flatten(Right, List3),
append(List2, List3, List).
我使用的查询是:
?- flatten(tree(tree(nil, 2, nil), 5, tree(nil, 6, nil)), L).
有没有人看到变量问题?我认为它可能在第一行(使用Item),但如果我将Item更改为item,则查询会立即返回false。
我只写了一些Prolog程序,所以这对我来说仍然是一个新概念。
答案 0 :(得分:2)
我相信E
应该更改为Val
。目前,Val
未使用(!)且E
来自任何地方。
此外,要使其正常运作,您应将Item
更改为nil
。
答案 1 :(得分:2)
有几个问题。让我们从最基本的一个开始:您正在拥有一个具有以下类型的树。
is_tree(nil).
is_tree(tree(L,_E,R)) :-
is_tree(L),
is_tree(R).
您的计划应该反映该类型。我说'打字'了吗?好吧,is_tree/1
与任何其他谓词一样。
另一个问题是你大量使用append/3
。并非没有原因,许多Prolog系统不提供append/3
,因为在dcg s的帮助下制定连接通常更为可取。
tree_elements(nil) --> []. tree_elements(tree(L,E,R)) --> tree_elements(L), [E], tree_elements(R).
现在你可以使用这个
?- phrase(tree_elements(tree(tree(nil, 2, nil), 5, tree(nil, 6, nil))), Es). Es = [2,5,6].
答案 2 :(得分:1)
@aioobe说的是什么。我认为你还比你应该使用append/3
更多。假设您的树表示如下:
tree( Left_subtree, Data , Right_subtree )
原子nil
代表一棵空树,我相信你可以达到同样的效果:
flatten( nil , [] ).
flatten( tree( Left , Data , Right ) , Flat ) :-
flatten( Left , Pfx ) ,
flatten( Right , Sfx ) ,
append( Pfx , [Data|Sfx] , Flat )
.