【问题标题】:Haskell - Find the longest word in a textHaskell - 查找文本中最长的单词
【发布时间】:2011-09-24 18:38:54
【问题描述】:

我遇到了一个问题,要编写一个函数来查找文本中最长的单词。

输入:一个包含很多单词的字符串。例如:"I am a young man, and I have a big house."

结果将是 5,因为文本中最长的单词有 5 个字母(young 和 house)。

我刚刚开始学习 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作为结果,但我不知道该怎么做,而且代码似乎也有问题。

有什么帮助吗?谢谢

【问题讨论】:

    标签: haskell text word


    【解决方案1】:

    尝试将您的任务拆分为多个子任务。我建议这样拆分:

    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 的实现留给读者作为练习。如果您需要帮助,请随时发表评论。

    【讨论】:

    • 可能toWords的最优实现是:"toWords = words"。
    • @ben No. 单词也会计算标点符号和数字。
    【解决方案2】:

    这里有几个问题。让我们从语法开始。

    您的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 函数在拆分输入时使用的标准略有不同。

    【讨论】:

      【解决方案3】:

      有几个问题

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

      maxord' [] _ n = n
      

      语法:

      maxord'(strs 0 m)
      

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

      maxord' strs 0 m
      

      m+1 应该是(m+1)

      您可能想要处理空字符串,但maxord 不允许。

      maxord s = maxord' s 0 0
      

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

      【讨论】:

        猜你喜欢
        • 2015-12-11
        • 2013-04-28
        • 1970-01-01
        • 1970-01-01
        • 2021-10-31
        • 2018-09-28
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多