2015-01-11 142 views
1

我在一本書中找到了一個很好的例子,我試圖解決這個問題。我正在嘗試編寫一個名爲「pointer」的函數,其簽名爲pointer :: String -> Int。它將帶有看起來像「Int」的「指針」的文本,然後返回找到的指針總數。通過字符串搜索

指針函數檢查會變成這樣的文字:

txt :: String 
txt = "[1] and [2] are friends who grew up together who " ++ 
     "went to the same school and got the same degrees." ++ 
     "They eventually opened up a store named [2] which was pretty successful." 

在命令行中,我們將運行代碼如下:

> pointer txt 
3 

3表示指針的數被發現。

我的理解:

  • 我得到的「字」將打破一個字符串與單詞的列表。 例如:

    單詞「這些蘋果都在哪裏?」

    [ 「在哪裏」, 「是」, 「全」, 「中」, 「這些」, 「蘋果?」]

  • 我得到的 「過濾器」 將選擇一個特定元素(S )列表中。 實施例:

    濾波器(> 3)[1,5,6,4,3]

     [5,6,4] 
    
  • 我得到 「長度」 將返回一個列表的長度

什麼,我認爲我需要做的:

Step 1) look at txt and then break it down into single words until you have a long list of words. 
Step 2) use filter to examine the list for [1] or [2]. Once found, filter will place these pointers into an list. 
Step 3) call the length function on the resulting list. 

存在問題:

我在試圖把我所知道的一切和實現它的過程中艱難的時間。

+0

所以你只是想計算字符串中出現'[1]'和'[2]'的次數? – ErikR

+2

編寫一個函數'f :: String - > Bool',如果輸入字符串是「指針」,則返回true。然後你的功能就像你描述的一樣:'長度。過濾器f。 words'。 – user2407038

回答

1

這是一個假設性的ghci的會話:

ghci> words txt 
[ "[1]", "and", "[2]", "are", "friends", "who", ...] 

ghci> filter (\w -> w == "[1]" || w == "[2]") (words txt) 
[ "[1]", "[2]", "[2]" ] 

ghci> length (filter (\w -> w == "[1]" || w == "[2]") (words txt)) 
3 

可以使最後一個表達式使用$操作更具可讀性:

length $ filter (\w -> w == "[1]" || w == "[2]") $ words txt 
1

如果你希望能夠找到類型的所有模式[Int]中的字符串 - 例如[3],[465]等不僅[1] [2]最簡單的辦法是使用正則表達式:

{-# LANGUAGE NoOverloadedStrings #-} 

import Text.Regex.Posix 

txt :: String 
txt = "[1] and [2] are friends who grew up together who " ++ 
     "went to the same school and got the same degrees." ++ 
     "They eventually opened up a store named [2] which was pretty successful." 

pointer :: String -> Int 
pointer source = source =~ "\\[[0-9]{1,}\\]" 

我們現在可以運行:

pointer txt 
> 3 
+1

由於默認情況下'OverloadedStrings'通常是關閉的,除非項目的'.cabal'文件默認打開它,否則不應該需要'{ - #LANGUAGE NoOverloadedStrings# - }'。 – dfeuer

1

這適用於單個數字 「指針」:

pointer :: String -> Int 
pointer ('[':_:']':xs) = 1 + pointer xs 
pointer (_:  xs) = pointer xs 
pointer _    = 0 

這樣更好地處理解析器組合器,如ie提供的那些。 Parsec,但這可能是矯枉過正。