如何在f#中使用给定的字符串列表为树编写remove函数?

时间:2018-11-29 09:55:06

标签: data-structures f# tree f#-3.0

我正在尝试编写一个'remove'函数,该函数可以根据给定的字符串列表的值删除树类型,但是使用该函数时我做不到正确的事,例如:

代码:

type Tree = Leaf of string | Branch of (string * Tree) list

let rec remove (p :string list) (tree: Tree) :Tree =
  match p, tree with
  | a::b, y  -> 
    match y with
    | Leaf(n) when a = n -> Leaf("") 
    | Branch[(x, p)] when a = x ->  Branch[("",  remove b p)]
    | _     -> remove b y
  | [], y    -> tree

测试:

remove ["1"; "2"; "3"; "4"]  
  (Branch [("6", Branch [("1", Branch [("2", Branch [("13", Leaf "4")])])])])

给出答案

Branch [("6", Branch [("1", Branch [("2", Branch [("13", Leaf "4")])])])]

代替

(Branch [("6", Branch [(" ", Branch [(" ", Branch [("13", Leaf " ")])])])])

如果有人可以帮助我,那会很好,因为我不明白自己在做什么错。

1 个答案:

答案 0 :(得分:1)

执行此操作的方式是同时遍历列表和树。这意味着您的代码只有在数字以要删除的项目列表中出现的顺序出现在树中时才能工作。

如果这是您真正想要的,则可以在函数中添加一种大小写以使其起作用:

let rec remove (p :string list) (tree: Tree) :Tree =
  match p, tree with
  | a::b, y  -> 
    match y with
    | Leaf(n) when a = n -> Leaf("") 
    | Branch[(x, p)] when a = x ->  Branch[("",  remove b p)]
    | Branch[(x, p)] -> Branch[(x, remove (a::b) p)] // Added this line!
    | _     -> remove b y
  | [], y    -> tree

当发现分支的编号不在列表开头时,添加的行可以处理这种情况-因此我们将分支保持不变,并继续从子树中删除数字。

也就是说,我想您可能想删除节点,而不管列表中元素的顺序如何。您可以使用List.contains之类的方法来检查是否应删除分支:

let rec remove (p :string list) (tree: Tree) :Tree =
  match tree with
  | Leaf(n) when List.contains n p -> Leaf("") 
  | Branch[(x, sub)] when List.contains x p ->  Branch[("",  remove p sub)]
  | Branch[(x, sub)] ->  Branch[(x, remove p sub)]

请注意,此代码仍缺少带有多个子树的分支的情况,因此您需要添加此内容,但希望示例可以为您指明正确的方向!