我的树遍历代码有什么问题?
我有一个简单的树,如此定义:
type BspTree =
| Node of Rect * BspTree * BspTree
| Null
我可以像这样获得叶节点(我的树“地牢”中的房间)的集合,并且它似乎有效:
let isRoom = function
| Node(_, Null, Null) -> true
| _ -> false
let rec getRooms dungeon =
if isRoom dungeon then
seq { yield dungeon }
else
match dungeon with
| Node(_, left, right) ->
seq { for r in getRooms left -> r
for r in getRooms right -> r }
| Null -> Seq.empty
但现在我正在尝试获取姐妹叶节点房间,这样我就可以用走廊把它们连接起来,我就失败了(就像我经常做的那样)。这是我的尝试:
let rec getCorridors dungeon =
match dungeon with
| Null -> failwith "Unexpected null room"
| Node(_, left, right) ->
match left, right with
| Null, Null -> Seq.empty
| Node(leftRect, _, _), Node(rightRect, _, _) ->
if isRoom left && isRoom right
then seq { yield makeCorridor leftRect rightRect }
else seq { for l in getCorridors left -> l
for r in getCorridors right -> r }
| _ -> failwith "Unexpected!"
我最终得到一个空的序列。无论如何,这一切都伤害了我的大脑,我知道不太可能有人会费力地完成它,但我认为问一下也没什么坏处。
I have a simple tree, defined thusly:
type BspTree =
| Node of Rect * BspTree * BspTree
| Null
I can get a collection of leaf nodes (rooms in my tree "dungeon") like this, and it seems to work:
let isRoom = function
| Node(_, Null, Null) -> true
| _ -> false
let rec getRooms dungeon =
if isRoom dungeon then
seq { yield dungeon }
else
match dungeon with
| Node(_, left, right) ->
seq { for r in getRooms left -> r
for r in getRooms right -> r }
| Null -> Seq.empty
But now I'm trying to get sister leaf node rooms so I can connect them with corridors, and I'm failing miserably (as I often do). Here's my attempt:
let rec getCorridors dungeon =
match dungeon with
| Null -> failwith "Unexpected null room"
| Node(_, left, right) ->
match left, right with
| Null, Null -> Seq.empty
| Node(leftRect, _, _), Node(rightRect, _, _) ->
if isRoom left && isRoom right
then seq { yield makeCorridor leftRect rightRect }
else seq { for l in getCorridors left -> l
for r in getCorridors right -> r }
| _ -> failwith "Unexpected!"
I just end up with an empty seq. Anyway, this all hurts my brain, and I know it's unlikely anyone will slog through it, but I figured it wouldn't hurt to ask.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如罗伯特评论的那样,也许你的 makeCorridor 函数需要一些关注。
我已经改编了您的代码,制作了我自己的 makeCorridor 函数并用 int 替换 Rect。
我使用了活动模式来确定 BspTree 何时是房间。我还使用过yield!序列而不是
对于序列中的x -> x。这些修改会导致相同的行为。我只是想展示活动模式可以做什么:
示例:
FSI 中的结果:
As Robert commented, maybe your makeCorridor function needs some attention.
I've adapted your code, making my own makeCorridor function and replacing Rect by int.
I've used an active pattern to determine when a BspTree is a room. I've also used
yield! sequence
instead offor x in sequence -> x
. These modifications result in the same behavior. I just wanted to show what an active pattern can do:Example:
Result in FSI: