Haskell 镜像树
任务是镜像一棵树(因此在每一级,最左边的子级都会变成最右边的子级,等等) 数据结构:Haskell 镜像树,haskell,Haskell,任务是镜像一棵树(因此在每一级,最左边的子级都会变成最右边的子级,等等) 数据结构: import Data.List data Rose a = Node a [Rose a] deriving (Eq, Show) mirror :: Rose a -> Rose a mirror (Node x []) = Node x [] mirror (Node x (y:ys)) = mirror (myReverse y) --reverses given node
import Data.List
data Rose a = Node a [Rose a]
deriving (Eq, Show)
mirror :: Rose a -> Rose a
mirror (Node x []) = Node x []
mirror (Node x (y:ys)) = mirror (myReverse y)
--reverses given node children
myReverse :: Rose a -> Rose a
myReverse (Node x y) = Node x (reverse y)
到目前为止我提出的问题:
import Data.List
data Rose a = Node a [Rose a]
deriving (Eq, Show)
mirror :: Rose a -> Rose a
mirror (Node x []) = Node x []
mirror (Node x (y:ys)) = mirror (myReverse y)
--reverses given node children
myReverse :: Rose a -> Rose a
myReverse (Node x y) = Node x (reverse y)
因此,当我使用示例运行此代码时:
Main> mirror (Node 1 [Node 11 [Node 111 [], Node 112[]], Node 12 [Node 121[]]])
函数返回我节点112[]
意味着它被卡在最左边的叶子上。从我的代码来看,这似乎是合乎逻辑的,因为我没有在y:ys
处传递给定节点子节点的尾部。不知何故,我必须能够反转给定节点的第一个子节点的所有子节点,并为相同的函数传递尾部。不管我怎么努力,我都无法做到这一点,而且看起来我已经达到了逻辑思维的极限
正如您正确指出的,在
mirror
函数中根本没有使用ys
,因此结果不可能是正确的
要解决这个问题,可以考虑一下Rose的递归结构,以及镜像是如何影响它的
也就是说,为了镜像一棵树,您必须保持它的根,并且(递归地)镜像它的每个子树,同时颠倒所述子树的顺序
如果这一点很清楚,那么只需要将这些单词翻译成Haskell代码
问问自己:
我会避免像第一个孩子和其他孩子那样用小的字眼来思考这个问题。相反,试着了解整个情况
a a
/ \ / \
b c ===> c b
/ | \ / \ / \ / | \
d e f g h h g f e d
如果我们递归地思考这个问题,我们可以观察到我们可以通过以下方式镜像一棵树:
反向
。要将函数f
应用于列表中的每个元素,可以使用map f
。试着看看你是否能把这些结合起来为自己解决问题
扰流板:
import Data.List
data Rose a = Node a [Rose a]
deriving (Eq, Show)
mirror :: Rose a -> Rose a
mirror (Node x []) = Node x []
mirror (Node x (y:ys)) = mirror (myReverse y)
--reverses given node children
myReverse :: Rose a -> Rose a
myReverse (Node x y) = Node x (reverse y)
镜像(节点a子节点)=节点a(反向$map镜像子节点)
1.要将一个函数应用于所有子函数,我必须递归地遍历它们。以列表的开头,应用函数并将主体传递给同一个函数。如何将所有自定义数据类型结果收集到一个列表中-我不知道,这就是导致我出现问题的原因。。。2.运行名为
myReverse
3的my helper函数。不,我不知道t@SYLARRR要将函数应用于列表中的每个元素,请使用map
:它将执行列表中所有繁琐的递归操作,因此您无需再次编写它。谢谢,使用内置函数map
,操作会简单得多。还有,$符号表示括号,我理解对了吗?如果没有$符号,扰流板结果将是mirror(Node a children)=Node a(reverse(map mirror children))
?@SYLARRR:是的,$
运算符的优先级非常低,因此您通常可以将其视为一个尽可能向右延伸的大左括号。嘿,这是我第一次看到有人在这个网站上使用扰流板。干得好