括弧の対応のチェック
30分プログラム、その782。anarchy golf - Bracket Matchingにインスパイアされました。
問題の詳細はリンク先を参照してください。要するに括弧の対応がとれているかどうかのチェックです。正規表現じゃ無理なことで有名なアレです。
簡易パーサコンビネータを書いて...、みたいなことも考えたのですが、まあこれぐらいなら明示的にスタックを持ち回れば十分でしょう。
使い方
- isParen ""; val it = true : bool - isParen "(<>)[]"; val it = true : bool - isParen "((("; val it = false : bool
ソースコード
structure Stack : sig type 'a t val push : 'a -> 'a t -> 'a t val pop : 'a t -> ('a * 'a t) val isEmpty : 'a t -> bool val empty : 'a t end = struct type 'a t = 'a list fun isEmpty [] = true | isEmpty _ = false fun push x xs = x :: xs fun pop (x::xs) = (x,xs) | pop [] = raise Empty val empty = [] end val map = [(#"(", #")"), (#"[", #"]"), (#"{", #"}"), (#"<", #">")] fun isBegin c = List.exists (fn (x,_) => c = x) map fun toBegin c = case List.find (fn (_,y) => y = c) map of NONE => raise Empty | SOME (x,_) => x fun paren [] st = Stack.isEmpty st | paren (c::cs) st = if isBegin c then paren cs (Stack.push c st) else let val (x,st') = Stack.pop st in if x = toBegin c then paren cs st' else false end fun isParen s = paren (String.explode s) Stack.empty