我有四种不同的节点类型。
leaf(Int)
node1(Leaf, Node1)
node2(Leaf, Node1, Node2)
node3(Leaf, Node1, Node2, Node3)
我正在寻找一个主要使用模式匹配的函数来检查树中是否有n
个节点的数量。例如,我运行函数计数器(Tree,c(1,2,1,3))如果Tree
有one leaf
,two single nodes
,one double nodes
,则返回true,和three triple nodes
。
我试图以两种不同的方式解决问题,但它们似乎都没有起作用。
第一种方法是使用辅助函数,其中辅助函数将通过Tree
并计算每种类型节点的数量。然后只需在其上运行is
。
第二种方法是从元组开始倒数,我们一进入就检查。如果我们点击一个有一个孩子的节点,我们从c(N1, N2, N3, N4)
转到c(N1, N2 - 1, N3, N4)
。
第一种方法的问题是,我正在尝试避免使用统一函数=
,因此任何想法如何在更新辅助函数中的元组的同时降低树的结构。
第二个问题是我无法知道它什么时候结束,因为它可以到达一片叶子但是我无法到达树的另一边继续并传递元组改变。
我认为解决这个问题的最佳方法是第一个。使用辅助函数,然后尝试自己查找树中的节点数。我可以相信还有其他方法可以解决这个问题,但这似乎是最有效的方法。
以下是第一种方法的代码:
countNodes(leaf(_), c(N1, N2, N3, N4)) :-
c(N0 + 1, N1, N2, N3).
countNodes(node1(_, Node), c(N1, N2, N3, N4)) :-
countNodes(Node, c(N1, N2 + 1, N3, N4)).
countNodes(node2(_, Node1, Node2), c(N1, N2, N3, N4)) :-
countNodes(Node1, c(N1, N2, N3 + 1, N4)),
countNodes(Node2, c(N1, N2, N3 + 1, N4)).
在那一点上它基本上崩溃了。我正在尝试两次添加计数节点,这意味着我们越往前走,它就越糟糕。关于如何重写它并避免在节点中有两个或三个子节点时重复计算的任何想法?
谢谢,任何帮助表示赞赏:)
答案 0 :(得分:1)
从您的代码开始,我提出以下建议(警告:未经测试)
countNodes(leaf(_), c(1, 0, 0, 0)).
countNodes(node1(_, Node), c(N1, N2, N3, N4)) :-
countNodes(Node, c(N1, N2a, N3, N4)),
N2 is N2a+1.
countNodes(node2(_, Node1, Node2), c(N1, N2, N3, N4)) :-
countNodes(Node1, c(N1a, N2a, N3a, N4a)),
countNodes(Node2, c(N1b, N2b, N3b, N4b)),
N1 is N1a+N1b,
N2 is N2a+N2b,
N3 is N3a+N3b+1,
N4 is N4a+N4b.
countNodes(node3(_, Node1, Node2, Node3), c(N1, N2, N3, N4)) :-
countNodes(Node1, c(N1a, N2a, N3a, N4a)),
countNodes(Node2, c(N1b, N2b, N3b, N4b)),
countNodes(Node3, c(N1c, N2c, N3c, N4c)),
N1 is N1a+N1b+N1c,
N2 is N2a+N2b+N2c,
N3 is N3a+N3b+N3c,
N4 is N4a+N4b+N4c+1.
如您所见,案例leaf
非常简单:您只需设置值1,0,0和0。
对于其他情况,您必须在子节点上递归调用countNodes
。接下来,您可以添加找到的值(使用is
)并为本地节点添加+1
。