我需要帮助定义一个prolog谓词treeMax(T,X)
,如果X
是存储在树T
中的最大数字,而不使用"是"谓词。
我使用函数术语来表示树:node1(X,T)
表示存储数字X
且有一个孩子node2(X,T1,T2)
和node3(X,T1,T2,T3)
的节点
术语leaf(X)
表示存储数字X
的叶子。
例如:node2(1,leaf(1),node3(9,leaf(9),leaf(10),leaf(11)))
是一棵树。
任何帮助都表示赞赏:)
编辑:最大子项数为3:因此可能的数据库为node1(X,T)
,node2(X,T1,T2)
,node3(X,T1,T2,T3)
和leaf(X)
。
答案 0 :(得分:0)
很抱歉,我不认为leaf/1
,node1/2
,node2/3
,node3/4
解决方案很好。
开发maxTree/2
很简单但是......
treeMax(leaf(M), M).
treeMax(node1(V0, N1), M) :-
treeMax(N1, V1),
M is max(V0, V1).
treeMax(node2(V0, N1, N2), M) :-
treeMax(N1, V1),
treeMax(N2, V2),
M is max(V0, max(V1, V2)).
treeMax(node3(V0, N1, N2, N3), M) :-
treeMax(N1, V1),
treeMax(N2, V2),
treeMax(N3, V3),
M is max(V0, max(V1, max(V2, V3))).
...但是,正如您所看到的,对于node4/5
,您必须制定另一个treeMax
子句,另一个用于node5/6
,另一个用于node6/7
, USW。
建议:保持节点和叶子之间的区别,但是对于节点,只实现一个带有值的结构和一个列表的子节点
所以你对子节点的数量没有限制;因此,您的maxTree/2
不需要与更多子树的附加条款集成。
所以你的例子变成了
node(1, [leaf(1), node(9, [leaf(9), leaf(10), leaf(11)])])
和maxTree/2
成为
treeMax(leaf(M), M).
treeMax(node(V0, LN), M) :-
treeMax(LN, V1),
M is max(V0, V1).
treeMax([N], M) :-
treeMax(N, M).
treeMax([Nh | Nt], M) :-
treeMax(Nh, V0),
treeMax(Nt, V1),
M is max(V0, V1).
---编辑---
抱歉:我现在看到你的"没有使用'是'谓词"
这是一个奇怪的要求,但可以做到。
您的解决方案非常痛苦(leaf/1
,node1/2
,node2/3
,node3/4
);我之前的解决方案变为
treeMax(leaf(M), M).
treeMax(node1(V0, N1), V0) :-
treeMax(N1, V1),
V1 =< V0.
treeMax(node1(V0, N1), V1) :-
treeMax(N1, V1),
V1 > V0.
treeMax(node2(V0, N1, N2), V0) :-
treeMax(N1, V1),
treeMax(N2, V2),
V1 =< V0,
V2 =< V0.
treeMax(node2(V0, N1, N2), V1) :-
treeMax(N1, V1),
treeMax(N2, V2),
V1 > V0,
V2 =< V1.
treeMax(node2(V0, N1, N2), V2) :-
treeMax(N1, V1),
treeMax(N2, V2),
V2 > V0,
V2 > V1.
treeMax(node3(V0, N1, N2, N3), V0) :-
treeMax(N1, V1),
treeMax(N2, V2),
treeMax(N3, V3),
V1 =< V0,
V2 =< V0,
V3 =< V0.
treeMax(node3(V0, N1, N2, N3), V1) :-
treeMax(N1, V1),
treeMax(N2, V2),
treeMax(N3, V3),
V1 > V0,
V2 =< V1,
V3 =< V1.
treeMax(node3(V0, N1, N2, N3), V2) :-
treeMax(N1, V1),
treeMax(N2, V2),
treeMax(N3, V3),
V2 > V0,
V2 > V1,
V3 =< V2.
treeMax(node3(V0, N1, N2, N3), V3) :-
treeMax(N1, V1),
treeMax(N2, V2),
treeMax(N3, V3),
V3 > V0,
V3 > V1,
V3 > V2.
如您所见,treeMax/2
需要leaf/1
条款,node1/2
需要两个条款,node2/3
需要三个条款,等等。
N+1
需要nodeN/N+1
个条款。
如果您使用基于单个node/2
结构的解决方案以及子节点列表,那么我之前的解决方案将成为
treeMax(leaf(M), M).
treeMax(node(V0, LN), V0) :-
treeMax(LN, V1),
V1 =< V0.
treeMax(node(V0, LN), V1) :-
treeMax(LN, V1),
V1 > V0.
treeMax([N], M) :-
treeMax(N, M).
treeMax([Nh | Nt], V0) :-
treeMax(Nh, V0),
treeMax(Nt, V1),
V1 =< V0.
treeMax([Nh | Nt], V1) :-
treeMax(Nh, V0),
treeMax(Nt, V1),
V1 > V0.
答案 1 :(得分:0)
这是一个比@ max66,&#34;折叠&#34;更简单的解决方案。树上的max/3
谓词。简化来自使用accumulator参数来存储中间结果。
tree_max(Tree, Max) :-
tree_max(Tree, 0, Max).
tree_max(leaf(N), Acc, Max) :-
max(N, Acc, Max).
tree_max(node1(Value, Subtree), Acc, Max) :-
max(Value, Acc, Acc1),
tree_max(Subtree, Acc1, Max).
tree_max(node2(Value, Left, Right), Acc, Max) :-
max(Value, Acc, Acc1),
tree_max(Left, Acc1, Acc2),
tree_max(Right, Acc2, Max).
tree_max(node3(Value, Child1, Child2, Child3), Acc, Max) :-
max(Value, Acc, Acc1),
tree_max(Child1, Acc1, Acc2),
tree_max(Child2, Acc2, Acc3),
tree_max(Child3, Acc3, Max).
max(A, B, Max) :-
Max is max(A, B).
max/3
的这种实现使用is/2
,但是(a)这是一种愚蠢的人为约束,而且(b)它很容易在没有max/3
的情况下重写is/2
。整个事情可以(也应该)推广到一般的tree_fold/4
谓词。
一些测试:
?- tree_max(node2(1,leaf(1),node3(9,leaf(9),leaf(10),leaf(11))), Max).
Max = 11.
?- tree_max(node2(1,leaf(1),node3(9,leaf(9),leaf(10),leaf(7))), Max).
Max = 10.
?- tree_max(node2(1,leaf(1),node3(9,leaf(42),leaf(10),leaf(7))), Max).
Max = 42.
?- tree_max(node2(1,leaf(23),node3(9,leaf(3),leaf(10),leaf(7))), Max).
Max = 23.