我试图用折返式创建给定一棵树和一个元素x的函数,如果该元素在树内,它将输出true,否则输出false。 这是我的树:
type 'a binTree =
| Null // empty tree
| Node of 'a * 'a binTree * 'a binTree
这是我的没有折返代码
let rec containsTreeBis bTree y =
match bTree with
| Null -> false
| Node(x,left,right) ->
match x=y with
| true -> true
| _ -> containsTreeBis left y || containsTreeBis right y
这是我的foldTree函数,可将折叠应用于树:
let rec foldTree f e tree =
match tree with
| Null -> e
| Node (x, left, right) ->
f x ( foldTree f e left ) ( foldTree f e right )
他们俩都表现不错。
现在是问题所在。
我尝试使用foldTree做同样的事情。 我真的很确信并确定这是正确的代码
let containsTreeF bTree pred =
foldTree ( fun y vl vr -> pred y || vl || vr ) true bTree
但是使用FsCheck进行了一些检查,结果是Falsiable。
我随机将代码更改为此:
let containsTreeF bTree pred =
foldTree ( fun y vl vr -> pred y || vl || vr ) false bTree
最后将true更改为false。
进行了FsCheck。有用。
如何?我不明白。
答案 0 :(得分:1)
您的fold
函数已正确实现,因此问题在于如何使用fold
函数检查树(或带有fold
操作的任何树)是否包含指定的元素
为此,您需要使用false
作为初始值,并使用逻辑or
作为操作,即:
let contains x tree =
foldTree (fun y vl vr -> x = y || vl || vr) false tree
这将为空树返回false
。如果任一分支包含元素,则true || false
将为true
,但是如果所有分支均不包含元素,则false || false
将得到false
。
当您将true
用作初始值时,为什么FsCheck测试没有捕获到该错误?有了该初始值,您的函数将始终返回true
,因此您可以通过测试查找不包含在树中的元素来捕获它。
对此的单元测试将是:
let t = Node(1, Node(2, Null, Null), Null)
contains 7 t
使用FsCheck,您可以根据某些随机生成的集合生成值的树,然后检查其中是否包含不在此集合中的项。