我是SML的新手。我试图检查二进制树中是否存在给定值。下面是代码的片段。执行后,它给出了
Warning : match nonexhaustive (n,Node (t1, j, t2)) => ...
我无法理解为什么会这样表现出来。我想我已经涵盖了所有可能的情况。任何人都可以给我提示或链接,这将有助于删除此警告。
datatype inttree = Empty | Node of inttree * int * inttree;
(*find(n,K) here n is the key that we have to find in inttree K*)
val rec find = fn(n, Node(t1,j,t2)) =>
let
val t = Node(t1, j, t2)
val compare = fn(i,j) => i = j
val find' =
fn (n,Empty) => false (* if we have reached the empty node then we are not able to find the key therefore return false *)
| (n,Node(t1,j,t2)) =>
if compare(n,j)
then true (* if value n and j are equal we have found the key n in the tree*)
else find(n,t1) orelse find(n,t2) (* if the value is not equal check in left subtree if found return true else check in the right subtree*)
in
find'(n,t)
end;
答案 0 :(得分:1)
鉴于您的数据类型声明,可以采用相当直接的递归方法。由于这似乎是家庭作业,我不想提供完整的解决方案,但这里有一个类似的功能:
fun allEven Empty = true
| allEven (Node(t1,i,t2)) =
if i mod 2 = 1 then false
else allEven t1 andalso allEven t2;
此函数返回true或false,具体取决于树中的所有整数是否均匀。它有一个基础案例
allEven Empty = true
(因为空树中没有奇数可用作反例)和递归情况
allEven (Node(t1,i,t2)) =
if i mod 2 = 1 then false
else allEven t1 andalso allEven t2;
如果节点处的整数是奇数,则返回false - 否则,如果对两个分支的递归调用求值为true,则返回true。
典型运行:
- allEven (Node(Node(Empty,3,Empty),5,Node(Node(Empty,6,Empty),7,Empty)));
val it = false : bool
- allEven (Node(Node(Empty,4,Empty),2,Node(Node(Empty,6,Empty),8,Empty)));
val it = true : bool
你的功能应该是这么长,并遵循相同的基本递归模式。
答案 1 :(得分:1)
val rec
外,您还可以撰写fun
并在=
的左侧指定参数。辅助函数compare
在很大程度上是多余的。您也可以使用=
。此外,人们称之为ML中的比较函数通常是返回 order 类型的函数,其值为LESS
,EQUALS
和GREATER
:
- Int.compare (3, 5);
> val it = LESS : order
在编写返回 bool 类型的if ... then true else ...
或类似语句时,您也可以使用组合器orelse
和andalso
。例如,您可以替换以下内容:
if compare(n,j)
then true
else find(n,t1) orelse find(n,t2)
使用:
n = j orelse find (n, t1) orelse find (n, t2)
很像内置函数List.exists
和List.all
将一个函数作为谓词并扫描一个列表,试图证明至少有一个元素存在,这是真的或者对所有元素都是如此,你可以创建函数treeExists
和treeForall
:
datatype intTree = Empty | Node of inttree * int * inttree;
fun treeExists f Empty = false
| treeExists f (Node (leftTree, x, rightTree)) =
f x orelse treeExists f leftTree orelse treeExists f rightTree
fun treeForall f Empty = true
| treeForall f (Node (leftTree, x, rightTree)) =
f x andalso treeForall f leftTree andalso treeExists f rightTree
使功能find
和allEven
变得更加简单:
fun find (x, tree) = treeExists (fn y => x = y) tree
fun allEven tree = treeForall (fn x => x mod 2 = 0) tree
因为所有的递归都留给了新的库函数。
以类似的方式,您可以treeMap
和treeFold
:
fun treeMap f Empty = Empty
| treeMap f (Node (leftTree, x, rightTree)) = ...
fun treeFold f e Empty = e
| treeFold f e (Node (leftTree, x, rightTree)) = ...
它们可用于在树中找到最大的绝对值:
fun maxAbsTree tree =
treeFold Int.max 0 (treeMap Int.abs tree)