Haskell - 找到文本中最长的单词

时间:2011-09-24 18:38:54

标签: haskell text word

我有一个问题就是写一个函数来找到文本中最长的单词。

输入:包含大量单词的字符串。例如:"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作为结果,但我不知道该怎么做,而且似乎代码也有问题。

有任何帮助吗?感谢

3 个答案:

答案 0 :(得分:13)

尝试将您的任务分成几个子任务。我建议像这样拆分:

  1. 将字符串转换为单词列表。例如,您的示例字符串变为

    ["I","am","a","young","man","and","I","have","a","big","house"]
    
  2. 列表上的
  3. map length。这会计算单词长度。例如,步骤1中的列表变为

    [1,2,1,5,3,3,1,4,1,3,5]
    
  4. 找到字符数最多的单词。您可以使用maximum

  5. 您可以使用将两个函数连接在一起的运算符(.)来组合这些步骤。例如,如果执行步骤1的函数被称为toWords,则可以在一行中执行整个任务:

    maxord = maximum . map length . toWords
    

    toWords的实施留给读者作为练习。如果您需要帮助,请随时写评论。

答案 1 :(得分: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函数在拆分输入时使用的标准略有不同。

答案 2 :(得分:2)

有几个问题

您的递归没有终止。您希望在处理完整个输入时返回n

maxord' [] _ n = n

语法:

maxord'(strs 0 m)

这意味着使用参数strs0调用m,然后将其用作maxord的参数。你不想做的是:

maxord' strs 0 m

m+1应为(m+1)

您可能希望处理空字符串,但maxord不允许它。

maxord s = maxord' s 0 0

应该这样做。有一些细微之处。 maxord'不要泄漏到命名空间,请使用where(max m n)比你使用的if-then-else更简洁。并查看其他答案,了解如何通过将内置的内容连接在一起来构建解决方案。递归更难阅读。