Haskell - 将后缀表达式转换为二叉树

时间:2017-08-21 14:48:19

标签: haskell recursion binary-tree postfix-notation

我正在尝试将postfix表达式转换为二叉树。我的函数将一个标记列表作为参数(字符串)。

每次我给函数任何输入时,调试器都会写一条消息:函数中的非详尽模式"添加"。

我的想法是:在令牌之后读取令牌并确定它是否是运算符或操作数。如果是操作数,则不要将任何节点保存到树中并将数字存储到堆栈中。否则,我创建一个带有运算符的节点,从堆栈弹出符号,将它们设置为新节点的子节点,并将运算符推送到堆栈。

如果字符串列表为空,则函数将打印二叉树。

有人会向我解释,为什么函数会给出非详尽的模式错误,我该如何修复这个函数?

data Tree = Leaf String | Empty | Node Tree String Tree deriving (Show)

add :: Tree -> [String] -> [Tree] -> Tree
add (Node l v p) [] stack = (Node l v p)
add Empty (x:xs) []
        | x `elem` ["*","-","+"] = add (Leaf x) xs [Leaf x]
        | otherwise = add Empty xs [Leaf x]
add Empty (x:xs) (a:b:bs)
        | x `elem` ["*","-","+"] = add (Node b x a) xs (Leaf x:a:b:bs)
        | otherwise = add Empty xs (Leaf x:a:b:bs)
add (Leaf x) token (a:b:bs)
        | x `elem` ["*","-","+"] = add (Node b x a) token (Leaf x:bs)
        | otherwise = Leaf x
add (Node l v p) (x:xs) (a:b:bs)
        | x `elem` ["*","-","+"] = add (Node b x a) xs (Leaf x:bs)
        | otherwise = add (Node l v p) xs (Leaf x:a:b:bs) 

parse :: String -> Tree
parse input = add Empty (words (toPostfix input)) []

1 个答案:

答案 0 :(得分:2)

我设法通过简单的例子重现错误:

add Empty ["10", "1", "+"] []

程序成功地将Leaf "10"添加到堆栈,但无法将Leaf "1"添加到堆栈,因为使用以下args调用add

add Empty ["1", "+"] [Leaf "10"]

但它并不匹配任何模式,因为add Empty (x:xs) (a:b:bs)期望第三个参数有两个Tree元素和一个列表。因此,需要将第三个参数与具有一个元素的列表匹配的模式。例如,添加:

add Empty (x:xs) [a] = add Empty xs (Leaf x:[a])

修复错误并打印以下内容:

Node (Leaf "10") "+" (Leaf "1")

希望它能帮助你继续完成任务,除非你已经解决了它:)