2009-07-05

逆波兰表达式计算器

今天在learnyouahaskell.com上看见一段逆波兰表达式计算器的代码,挺美妙的。
solveRPN :: (Num a, Read a) => String -> a
solveRPN = head . foldl foldingFunction [] . words
where foldingFunction (x:y:ys) "*" = (x * y):ys
foldingFunction (x:y:ys) "+" = (x + y):ys
foldingFunction (x:y:ys) "-" = (y - x):ys
foldingFunction xs numberString = read numberString:xs

第一行是函数solveRPN的类型声明,略过。简单的流程解释一下就是:先用words将字符串tokenize,然后用上foldl扫描归纳之,最后将结果存在list的第一个节点,用head取出来。简单明了,一气呵成。比如,给定字符串"10 8 + 2 -"。下面是归纳步骤。

words "10 8 + 2 -" 得到 ["10", "8", "+", "2", "-"],接下来便是:foldl [] ["10", "8", "+", "2", "-"]。应用传递给foldl的函数foldingFunction,得到运算过程:

  1. fold1 [] "10" [""8", "+", "2", "-"]

  2. foldl [10] [""8", "+", "2", "-"]

  3. foldl [10, 8] ["+", "2", "-"]

  4. foldl [18] ["2", "-"]

  5. foldl [18, 2] ["-"]

  6. foldl [20]


foldl结束后head [20],便得到20。需要注意的是第六行,它的意思是(read numberString) : xs,而不是read (numberString:xs)。优先级问题哈。

标签:

0 Comments:

发表评论

<< Home