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)