【问题标题】:finding the number of occurrences of a variable in a binary tree in haskell在haskell中查找二叉树中变量的出现次数
【发布时间】:2012-04-04 10:58:54
【问题描述】:

我想在任何树中找到某个数字的出现次数。这是我的代码,但它给出了一个错误,我无法找到它发生的原因。

data Tree a = Empty | Node (a ,Tree a,Tree a) deriving (Show)

occurst _ Empty = 0     -- this line occurs error
occurst a ( Node (x,left,right) ) = if x==Empty then 0
            else if a==x then 1 + (occurst a left) + (occurst a right)
            else (occurst a left) + (occurst a right)  


j=let t = Node (3 , Node (2 , Node (1 , Empty , Empty ) , Node (1 , Empty , Empty )),Node     (1 , Node (2 , Node (1 , Empty , Empty ) , Node (1 , Empty , Empty )),Node    (1,Empty,Empty)))  
  in occurst 1 t

错误信息是:

ERROR "treeExample.hs":95 - Cannot infer instance
*** Instance   : Eq (Tree a)
*** Expression : occurst

输入输出必须是:

occurst 1 t -> 6
occurst 2 t -> 2
occurst 3 t ->1
occurst 4 t ->0

【问题讨论】:

  • 为什么Node 需要一个元组? Node a (Tree a) (Tree a) 怎么了?

标签: haskell binary-tree


【解决方案1】:

你可以非常简洁地编写你的函数:

occurst _ Empty = 0   
occurst a ( Node (x,left,right) ) = 
   fromEnum (x==a) + (occurst a left) + (occurst a right)  

fromEnumEnum 转换为Int,幸运的是不仅Bool 实际上是Enum,而且False 映射到0,True 映射到1。

【讨论】:

    【解决方案2】:

    一行有bug

    occurst a ( Node (x,left,right) ) = if x==Empty then 0
    

    你是说xTree ......真的不知道这个if 是干什么用的

    这将按预期工作:

    data Tree a = Empty | Node (a ,Tree a,Tree a) deriving (Show, Eq)
    
    occurst _ Empty = 0
    occurst a ( Node (x,left,right) ) =
                if a==x then 1 + (occurst a left) + (occurst a right)
                else (occurst a left) + (occurst a right) 
    

    顺便说一句:我没有改变你的命名也没有改变你的基本算法,但请注意这个不是很友好的堆栈,因为它不是尾递归的。

    【讨论】:

    • 他们不需要告诉 Haskell Tree 是 Eq 的一个实例 --- 整个尝试比较树的事情都是一个错误(在这个函数中)。
    • Dave 是对的,抱歉——如果你按照编译器告诉你的去做,你会得到什么;)
    • 如何使这个尾递归?你会积累一个尚未访问的子树列表吗?这比让堆栈更有效吗?
    • 延续不会神奇地将线性空间算法变成常数空间算法。
    • 这个问题是针对尾递归算法的......但没关系,这曾经是并且不是这里的主题(你可以在这里找到关于该主题的问题:stackoverflow.com/questions/9323036/…
    【解决方案3】:

    这是一个尾递归版本:

    data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)
    
    occurst x t = go 0 [t] where
      go n [] = n
      go n (t:ts) = case t of
                      Empty      -> go n ts
                      Node a l r -> let n' = n + fromEnum (a==x)
                                    in n' `seq` go n' (l:r:ts)
    
    j = occurst 1 t where
      t = (Node 3
            (Node 2
              (Node 1 Empty Empty)
              (Node 1 Empty Empty ))
            (Node 1
              (Node 2
                (Node 1 Empty Empty)
                (Node 1 Empty Empty))
              (Node 1 Empty Empty)))
    

    【讨论】:

    • 不过,您需要为n 添加一些严格性,可以使用seq 或爆炸模式。否则你只会建立一个大的thunk。
    • @hammar,呵呵!固定(我认为)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    相关资源
    最近更新 更多