2011-09-24 91 views
3

我有一個關於編寫函數以查找文本中最長單詞的問題。Haskell - 查找文本中最長的單詞

輸入:有很多單詞的字符串。例如:"I am a young man, and I have a big house."

結果將是5,因爲文本中最長的單詞有5個字母(年輕人和家庭)。

我剛開始學習Haskell。我已經試過:

import Char 
import List 

maxord' (str:strs) m n = 
    if isAlpha str == True 
    then maxord'(strs m+1 n) 
else if m >= n 
     then maxord'(strs 0 m) 
    else maxord'(strs 0 n) 

maxord (str:strs) = maxord' (str:strs) 0 0 

我想回到n的結果,但我不知道如何做到這一點,似乎也有一些錯誤的代碼。

任何幫助?謝謝

回答

4

這裏有幾個問題。讓我們從語法開始。

else部分應縮進相同或作爲if他們屬於更多,比如像這樣:

if ... 
then ... 
else if ... 
    then ... 
    else ... 

接下來,你的功能的應用。與許多其他語言不同的是,在Haskell中,圓括號僅用於分組和元組的。由於函數應用在Haskell中很常見,所以我們使用最輕量級的語法,即空格。因此,要將函數maxord'應用於參數strsm+1n,我們編寫了maxord' strs (m+1) n。請注意,由於函數應用程序的優先級最高,因此我們必須在m+1附近添加括號,否則將被解釋爲(maxord' strs m) + (1 n)

就是這樣的語法。下一個問題是一個語義問題,即你沒有基本案例遞歸的。使用模式(str:strs),您指定了在剩下一些字符時要執行的操作,但未指定在到達字符串末尾時應執行的操作。在這種情況下,我們想返回n,所以我們爲此添加一個案例。

maxord' [] m n = n 

固定maxord'因此

maxord' [] m n = n 
maxord' (str:strs) m n = 
    if isAlpha str == True 
    then maxord' strs (m+1) n 
    else if m >= n 
     then maxord' strs 0 m 
     else maxord' strs 0 n 

但是請注意,這個解決方案不是很地道。它使用顯式遞歸,if表達式而不是看守,將布爾值與True進行比較,並且具有非常必要的感覺。更習慣的解決方案就是這樣的。

maxord = maximum . map length . words 

這是一個簡單的函數鏈,其中words輸入分裂成單詞的列表,map length替換每個字與它的長度,和maximum返回最大那些長度。

儘管請注意,它與您的代碼不完全相同,因爲words函數在分割輸入時使用稍微不同的條件。

13

嘗試將您的任務分成幾個子任務。我建議這樣的分裂是:

  1. 打開串入一個單詞列表。例如,您的示例字符串變成

    ["I","am","a","young","man","and","I","have","a","big","house"] 
    
  2. map length在列表上。這會計算字長。例如,在步驟1中的列表變得

    [1,2,1,5,3,3,1,4,1,3,5] 
    
  3. 找到與角色的最多的一句話。你可以使用maximum這個。

可以構成使用操作(.)其中管道兩個功能一起的那些步驟。例如,如果執行步驟1中的函數被調用toWords,您可以在一個行執行整個任務:

maxord = maximum . map length . toWords 

toWords實現留作鍛鍊; Tibial給讀者。如果您需要幫助,請隨時發表評論。

+0

不錯的解決方案!很有幫助!謝謝你:) – Ferry

+0

@Ferry你知道嗎,你可以通過點擊投票計數下面的灰色勾號形(✓)符號來標記答案。 – fuz

+1

toWords的最佳實現可能是:「toWords = words」。 –

2

有幾個問題

沒有終止你遞歸。您在處理完整個輸入時要返回n

maxord' [] _ n = n 

語法:

maxord'(strs 0 m) 

這意味着調用應用strs與參數0m,然後用它作爲參數傳遞給maxord。你wan't做的是這樣的:

maxord' strs 0 m 

m+1應該(m+1)

您可能想要處理空字符串,但maxord不允許它。

maxord s = maxord' s 0 0 

這應該做到這一點。有一些微妙之處。 maxord'不應泄漏到名稱空間,請使用where(max m n)比if-then-else更簡潔。並查看其他答案,瞭解如何通過將內置的東西連接在一起來構建解決方案。遞歸很難閱讀。