2013-04-24 36 views

回答

9

聚集在jozefg的解決方案几乎是相同的什麼,我想出了(我完全同意他的建議),也有讓我覺得,我應該發佈第二一些小的區別回答:

  1. 由於初始示例的預期結果,沒有必要將空格分隔的部分視爲單獨的子樹。
  2. 此外,看到實際計算預期結果的部分(即字符串列表)可能很有趣。

所以這裏是我的版本。正如jozefg所建議的那樣,將任務分成幾個子任務。它們是:

  1. 將字符串解析爲表示某種樹的代數數據類型。
  2. 收集此樹的(期望的)子樹。
  3. 將樹變成字符串。

關於1,我們首先需要的是一棵數據類型

import Text.Parsec 
import Text.Parsec.String 
import Control.Applicative ((<$>)) 

data Tree = Leaf String | Node [Tree] 

,然後一個功能,可以解析字符串到這種類型的值。

parseTree :: Parser Tree 
parseTree = node <|> leaf 
    where 
    node = Node <$> between (char '(') (char ')') (many parseTree) 
    leaf = Leaf <$> many1 (noneOf "()") 

在我的版本我認爲括號之間的孔字符串作爲Leaf節點(即我沒有在白空間分割)。

現在,我們需要收集樹我們感興趣的子樹:

nodes :: Tree -> [Tree] 
nodes (Leaf _) = [] 
nodes [email protected](Node ts) = t : concatMap nodes ts 

最後,Show -instance爲Tree允許的數量我們將它們變成字符串。

instance Show Tree where 
    showsPrec d (Leaf x) = showString x 
    showsPrec d (Node xs) = showString "(" . showList xs . showString ")" 
    where 
     showList [] = id 
     showList (x:xs) = shows x . showList xs 

那麼原來的任務是可以解決的,例如,通過:

parseGroups :: Parser [String] 
parseGroups = map show . nodes <$> parseTree 

> parseTest parseGroups "((a b c) a b c)" 
["((a b c) a b c)","(a b c)"] 
+0

Awsome回答非常感謝。我更喜歡這種方法 – user2150839 2013-04-24 06:52:31

+0

@chris我試過這個,我看到它的一個問題..節點功能複製所有嵌套括號的內容。當我將最後一行節點函數替換爲此節點時,它的工作方式應該如此:'節點t @(節點_)= t' – 2016-02-15 23:06:59

+0

P.S.啊,我明白這是OP的要點。不要那麼:-)我需要一些不同的東西 - 只是爲了解析圓括號的內容,其中包括圓括號。像'func(){hello {...}}',但內容變平。有了這個簡單的改變,它就做到了我所需要的,所以非常感謝! – 2016-02-15 23:14:50

10

我會使用一個遞歸解析:

data Expr = List [Expr] | Term String 

expr :: Parsec String() Expr 
expr = recurse <|> terminal 

其中terminal是你的原語,在這種情況下,這些似乎是個字符的字符串,這樣

where terminal = Term <$> many1 letter 

recurse

 recurse = List <$> 
        (between `on` char) '(' ')' (expr `sepBy1` char ' ') 

現在我們有一棵漂亮的樹Expr sw HICH我們可以

collect [email protected](List ts) = r : concatMap collect ts 
collect _   = [] 
+0

也許這只是我),但我覺得'(R $ :) TS >> =收集真的很難讀。不會'':concatMap收集ts'更具可讀性?但除了口味問題,我認爲基本情況不應該只返回'[]'。 – chris 2013-04-24 05:24:10

+0

哦,對不起,我的錯誤。基本情況下需要'[]'(因爲我們只希望在結果中使用圓括號)。 – chris 2013-04-24 05:45:11

+0

@chris嗯是的...我一直在努力的代碼,這就是列表monad重,我會編輯 – jozefg 2013-04-24 09:04:32

相關問題