Haskell 检查字符串是否由平衡圆括号组成
我编写了以下程序来检查字符串的平衡括号:Haskell 检查字符串是否由平衡圆括号组成,haskell,recursion,pattern-matching,formal-languages,pushdown-automaton,Haskell,Recursion,Pattern Matching,Formal Languages,Pushdown Automaton,我编写了以下程序来检查字符串的平衡括号: isBalanced xs = isBalanced' xs [] isBalanced' [] [] = True isBalanced' [] _ = False isBalanced' ('(':xs) ys = isBalanced' xs (')':ys) isBalanced' ('[':xs) ys = isBalanced' xs (']':ys) isBalanced' ('{':xs) ys = isBalanced' xs (
isBalanced xs = isBalanced' xs []
isBalanced' [] [] = True
isBalanced' [] _ = False
isBalanced' ('(':xs) ys = isBalanced' xs (')':ys)
isBalanced' ('[':xs) ys = isBalanced' xs (']':ys)
isBalanced' ('{':xs) ys = isBalanced' xs ('}':ys)
isBalanced' _ [] = False
isBalanced' (x:xs) (y:ys) = (x == y) && (isBalanced' xs ys)
以下是一些示例数据:
positives = [
isBalanced "",
isBalanced "()",
isBalanced "[]",
isBalanced "{}",
isBalanced "([]){}[{}]"
]
negatives = [
isBalanced "(",
isBalanced "[",
isBalanced "{",
isBalanced ")",
isBalanced "]",
isBalanced "}",
isBalanced "([)]",
isBalanced "{]",
isBalanced ")("
]
由于这个程序只使用显式递归的最基本的构建块,我想知道是否有一种更短、更高级的方法涉及到我还不知道的语言设施
好的,我从几个答案和评论(以及我自己的想法)中提炼出以下解决方案:
import Text.Parsec
语法=多个参数>>返回(),其中
parens=选择[在(字符开始)(字符结束)语法之间]
|[开始、结束]>eof“
isRight(Right u)=真
isRight=False
对于这么简单的问题,可能有点过头了,但您可以尝试查找
作为更基本的简化,您可以将递归重写为将一个堆栈和字符串中的一个字符折叠到一个新的堆栈中的函数。(不过,这是否会使它变得更简单,这是旁观者的看法)。正如解析器组合器所做的那样。下面是一个使用:
我认为哈马尔的答案是最好的,但这里有一些你可以做的小步骤-使用
null
和lookup
:
{-# LANGUAGE PatternGuards #-}
isBalanced xs = isBalanced' xs []
isBalanced' [] x = null x
isBalanced' (c:xs) ys | Just d <- lookup c par = isBalanced' xs (d:ys)
where par = [('(',')'), ('[',']'),('{','}')]
isBalanced' _ [] = False
isBalanced' (x:xs) (y:ys) = x == y && isBalanced' xs ysl
{-#语言模式卫士}
isBalanced xs=isBalanced'xs[]
isBalanced'[]x=null x
isBalanced'(c:xs)ys |使用左折叠仅d
折叠会建立一个以前遇到的字符的堆栈,在找到匹配的字符时将其剥离。如果以空列表结束,则字符串是平衡的
在Maybe monad中使用左折叠
使用左折叠的缺点是必须始终扫描整个字符串。如果在没有匹配的左大括号的情况下发现右大括号,则最好在出现故障的情况下中止操作。下面的版本就是这样做的
import Control.Monad (foldM)
isBalanced' xs = maybe False null $ foldM op [] xs
where
op ('(':xs) ')' = Just xs
op ('[':xs) ']' = Just xs
op ('{':xs) '}' = Just xs
op xs x | x `elem` ")]}" = Nothing
| otherwise = Just (x:xs)
确实,解析器组合符是有用的。类似于拥抱s left right=char left*>s@Rotsor的代码看起来不正确。是否应该是空的…
而不是类似于多(…)
(例如,尝试解析“()”
)@丹尼尔,哦,的确……而且,运算符的优先级是错误的。甚至braces=choice[between(char o)(char c)grammar |(o,c)是平衡的“0”==False
{-# LANGUAGE PatternGuards #-}
isBalanced xs = isBalanced' xs []
isBalanced' [] x = null x
isBalanced' (c:xs) ys | Just d <- lookup c par = isBalanced' xs (d:ys)
where par = [('(',')'), ('[',']'),('{','}')]
isBalanced' _ [] = False
isBalanced' (x:xs) (y:ys) = x == y && isBalanced' xs ysl
import Data.List (foldl')
isBalanced xs = null $ foldl' op [] xs
where
op ('(':xs) ')' = xs
op ('[':xs) ']' = xs
op ('{':xs) '}' = xs
op xs x = x:xs
import Control.Monad (foldM)
isBalanced' xs = maybe False null $ foldM op [] xs
where
op ('(':xs) ')' = Just xs
op ('[':xs) ']' = Just xs
op ('{':xs) '}' = Just xs
op xs x | x `elem` ")]}" = Nothing
| otherwise = Just (x:xs)