Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 镜像树_Haskell - Fatal编程技术网

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代码

问问自己:

  • 如何将函数应用于每个子级并在列表中收集结果

  • 我怎样才能按相反的顺序做1

  • 我真的需要单独处理空列表案例吗


  • 我会避免像第一个孩子和其他孩子那样用小的字眼来思考这个问题。相反,试着了解整个情况

                    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:是的,
    $
    运算符的优先级非常低,因此您通常可以将其视为一个尽可能向右延伸的大左括号。嘿,这是我第一次看到有人在这个网站上使用扰流板。干得好