四則演算のみサポートする単純な処理である。
Haskellの場合
module RPN wheresolveRPN :: String -> Double
solveRPN = head . foldl func [] . words
where
func (x:y:ys) "+" = (y + x) : ys
func (x:y:ys) "-" = (y - x) : ys
func (x:y:ys) "*" = (y * x) : ys
func (x:y:ys) "/" = (y / x) : ys
func xs num = read num : xs
*RPN> solveRPN "1 2 + 3 * 1 - 2 /"
4.0
whereを使うとコードが分かり易くて、なかなか良いね。
Clojureの場合
(ns rpn.core(:use [clojure.string :only (split)]))
(defn words [s]
(split s #"\s+"))
(defn op2 [[x y & ys] f]
(conj ys (apply f [y x])))
(defn operate [stack item]
(case item
"+" (op2 stack +)
"-" (op2 stack -)
"*" (op2 stack *)
"/" (op2 stack /)
(conj stack (Double/parseDouble item))))
(defn solve-rpn [exprs]
(first (reduce operate '() (words exprs))))
rpn.core> (solve-rpn "1 2 + 3 * 1 - 2 /")
4.0
solve-rpn関数の中でoperate関数を定義することも可能だが、かえって分かり難くなりそうなので、外出しして関数定義した。
Haskellに比べると冗長になってしまった。
もっと、すっきり書けるのかな?
文字列のdouble型への変換 (Double/parseDouble item) は美しくない。→と思ったときは parse-double関数を作れば良いのだけど。
0 件のコメント:
コメントを投稿