F#基础任意树实现、checkstuff函数使用及扩展问题咨询
F# 树结构实现与常见操作解答
原代码问题说明
你当前的checkstuff函数存在两个核心问题:
- 逻辑缺失:没有对节点存储的字符串做判断,只要匹配到
Leaf就直接返回true,所以任意Leaf调用都会返回true - 参数设计错误:仅接收一个
Tree类型参数,你写的t2 |> checkstuff (Leaf "z")会优先计算checkstuff (Leaf "z")得到布尔值,再尝试把t2传入布尔值执行,自然触发类型不匹配报错
问题1:节点存在性检查实现与调用示例
正确的存在性检查函数
首先改造函数,增加目标搜索字符串参数,递归判断每个节点的值是否匹配:
// 第一个参数为要搜索的目标字符串,第二个参数为树节点 let rec contains (target: string) (tree: Tree) = match tree with | Leaf value -> value = target | Branch (nodeValue, children) -> // 先判断当前节点是否匹配,不匹配再遍历所有子节点 nodeValue = target || List.fold (fun acc child -> acc || contains target child) false children
List.fold逻辑解释
你提到的List.fold (||) false (List.map checkstuff children)逻辑本质是:
- 初始累加值为
false - 遍历子节点的检查结果列表,每一步将当前累加值与子节点结果做布尔或运算
- 只要有任意一个子节点返回
true,最终累加结果就为true
可运行调用示例
// 直接调用:检查t2中是否存在字符串"c",返回true contains "c" t2 // 直接调用:检查t2中是否存在字符串"z",返回false contains "z" t2 // 管道运算符调用:优先传入树参数,符合柯里化偏应用规则 t2 |> contains "f" // 返回true
问题2:功能扩展实现
1. 树中所有字符串拼接
let rec concatAll (tree: Tree) = match tree with | Leaf value -> value | Branch (nodeValue, children) -> // 拼接当前节点值 + 所有子节点拼接结果 nodeValue + (children |> List.fold (fun acc child -> acc + concatAll child) "") // 调用示例,返回"abcdefg" concatAll t2
2. 指定模式匹配查询
以正则匹配为例,返回所有符合规则的字符串列表:
open System.Text.RegularExpressions let rec findByPattern (pattern: string) (tree: Tree) = let isMatch s = Regex.IsMatch(s, pattern) match tree with | Leaf value -> [ if isMatch value then yield value ] | Branch (nodeValue, children) -> let currentResult = [ if isMatch nodeValue then yield nodeValue ] let childrenResult = children |> List.collect (findByPattern pattern) currentResult @ childrenResult // 调用示例:查询所有以b/e开头的字符串,返回["b"; "e"] findByPattern "^[be]" t2
补充说明
你后续遇到的括号问题是F#新手常见问题:F#默认采用柯里化的函数参数设计,多参数不需要包裹在同一对括号中,每个参数单独加括号注解类型即可;管道运算符|>会将左侧的值作为右侧函数的最后一个参数传入,偏应用时要注意参数顺序的设计。
内容的提问来源于stack exchange,提问作者diopside
相关产品推荐
相关产品推荐

