来访的每个节点 [英] visiting each node

查看:123
本文介绍了来访的每个节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个爱好项目,该项目是关于建立一个树来储存识别号码。我已经使用的数字,存储在节点,也就是节点可以是0 1 2 3 4 5 6 7 8 9

I have a hobby project which is about creating a tree to store identification numbers. I had used digit, stored at node, that is node can be 0 1 2 3 4 5 6 7 8 9.

在我创建的树,我想从树上组成名单。但是,我无法找到一个算法来管理我的目标。

After I have create tree, I want compose list from tree. But, I could not find a algorithm to manage my goal.

我想:

      "recompose tree"  will return list of numbers. For below tree it should be 

            [ 2, 21, 243, 245, 246, 78, 789 ]  


                               Root 
                           /          \         
                        2*               7
                      /      \             \                  
                   1*         4              8*    
                            / \  \            \         
                           3*  5* 6*           9*

       my data type :  data ID x = ID ( ( x, Mark ), [ ID x ] ) 
                       data Mark = Marked | Unmarked

       EDIT:

       for convenience : * shows it is marked
                         I have stored digit as char, actually not 1, 
                            it is stored as'1' 

你有建议我怎么能做到这一点? (建议是pfferred是算法$ P $)

Do you have advice how I can do that ? ( advice is prefferred to be algorithm )

推荐答案

什么

recompose :: Num a => ID a -> [a]
recompose = go 0
  where
    go acc (ID ((n, Marked), ids)) =
      let acc' = 10 * acc + n
      in  acc' : concatMap (go acc') ids
    go acc (ID ((n, Unmarked), ids)) =
      let acc' = 10 * acc + n
      in  concatMap (go acc') ids

这就是我们遍历树,同时积累了从根的路径节点的值。在每一个节点,我们通过乘以10的路径值,并增加了对节点给它的值更新累加器。遍历产生了显着的节点,所有累加器值的列表:那么,在明显的节点,我们累加器值添加到列表中,未标记的节点,我们只是宣传,我们已经收集了节点的子节点列表

That is, we traverse the tree while accumulating a value for the path from the root to a node. At every node we update the accumulator by multiplying the value for the path by 10 and adding the value for the node to it. The traversal produces a list of all accumulator values for marked node: so, at marked node we add the accumulator value to the list, for unmarked nodes we just propagate the list that we have collected for the children of the node.

我们如何计算列表中一个节点的孩子?我们通过递归过来的孩子的名单映射调用穿越功能()的所有儿童。这给了我们,我们串联,以获得一个列表中列出的清单。 ( concatMap˚FXS 只是 CONCAT(映射f XS)) CONCAT。映射f

How do we compute the list for the children of a node? We recursively call the traversal function (go) to all children by mapping it over the list of children. That gives us a list of lists that we concatenate to obtain a single list. (concatMap f xs is just concat (map f xs)) or concat . map f.)

在属性语法术语:累加器作为一个继承的属性,而返回的列表是一个综合属性

In attribute-grammar terminology: the accumulator serves as an inherited attribute, while the returned list is a synthesised attribute.

作为一个细化,我们可以引入一个辅助功能 ISMARKED

As a refinement, we can introduce an auxiliary function isMarked,

isMarked :: Mark -> Bool
isMarked Marked   = True
isMarked Unmarked = False

这样我们就可以简洁地写

so that we can concisely write

recompose :: Num a => ID a -> [a]
recompose = go 0
  where
    go acc (ID ((n, m), ids)) =
      let acc'   = 10 * acc + n
          prefix = if isMarked m then (acc' :) else id
      in  prefix (concatMap (go acc') ids)

这篇关于来访的每个节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆