我想在Prolog中编写一个程序,它构建一个驻留在b树中的所有偶数整数的列表。 这就是我到目前为止所写的内容。一个谓词,计算树中的所有元素。我不知道在哪里划伤。
Domains
element=integer
tree=a(tree,element,tree);void
list=integer*
Predicates
nondeterm count(tree,element)
nondeterm count_even(tree,list)
Clauses
count(a(void,Number,void),1).
count(a(Esq,_,Dreta),Counter) :-
count(Esq,Counter1),
count(Dreta,Counter2),
Counter=Counter1+Counter2+1.
Goal
count(a(a(void,1,void),5,a(a(void,4,void),1,a(void,4,void))),N).
非常感谢。
答案 0 :(得分:1)
Dunno关于Visual Prolog的一切,但在正常的Prolog中,我会做类似以下的事情......
首先,我将一个空的btree表示为原子btree
,并将一个非空的btree表示为arity 3的结构,因此:
btree( Payload, LeftChildren, RightChildren )
其中Payload
是节点的数据(显然是一个整数),LeftChildren
和RightChildren
分别代表当前节点的左子节点和右子节点。
遍历树以计算具有偶数节点的节点很简单。公共谓词具有arity 2,接受要检查的[bound] btree结构,以及表示偶数项的计数的绑定或未绑定值。它调用一个内部的,递归的“帮助器”谓词,它可以走一棵树并开发计数。
count_even( T , N ) :- count_even( T , 0 , N ) .
内部谓词也很简单。有了arity 3,第一个参数是要检查的树,第二个是累加器,第三个是最终计数(直到最后才会统一)。有两种可能的情况。
如果树是空的,我们有最终计数:
count_even( btree , N , N ) .
如果树是非空的,我们检查当前节点,然后递归地遍历左右子树,因此:
count_even( btree( V , L , R ) , T , N ) :-
is_even( V , X ) ,
T1 is T+X ,
count_even( L , T1 , T2 ) ,
count_even( R , T2 , N )
.
我们还需要一个简单的帮助器来告诉我们特定值是偶数还是奇数:
is_even( V , 1 ) :- 0 is V mod 2 , ! .
is_even( V , 0 ) .
应该注意的是,您使用的数据结构不是b树,本身:它是二叉树。
B树是针对磁盘存储优化的高度平衡二叉树的概括。每个节点具有可变数量的键和可变数量的子节点(对应于键的数量)。有关更多信息,请参阅
这是B树的图片:
二叉树的图片:
答案 1 :(得分:0)
你必须检查每个节点,看它是偶数还是奇数,只计算偶数。 你的程序应该做一个简单的修改(但是我会做的有点不同):
element=integer
tree=a(tree,element,tree);void
list=integer*
Predicates
nondeterm count_even(tree,list)
Clauses
count_even(a(void,Number,void),Value):-
Value = 1 - Number mod 2.
count_even(a(Esq,Number,Dreta),Counter) :-
count_even(Esq,Counter1),
count_even(Dreta,Counter2),
count_even=Counter1 + Counter2 + 1 - Number mod 2.
我只计算1 - Number mod 2
,当数字为偶数时为1,否则为0。