【问题标题】:Last element of two list recursion两个列表递归的最后一个元素
【发布时间】:2021-07-12 00:46:11
【问题描述】:

这是家庭锻炼的一部分,我已经考虑过了,但不了解最后一个障碍。

任务的想法是实现不寻常的子字符串函数,其工作方式如下:

编写一个函数commonSubstring :: String -> String -> String,给定两个字符串s1s2,计算s1s2 的公共“子字符串”,如下所示。该函数查找最早的公共字符c(最接近出现在两个序列中的s1s2head)。该函数删除两个字符串中的c 及其前面的所有字符,将c 放入输出字符串中,然后继续。

如果最早的常用字符有两个候选,请从s1 中选择一个。

调用此类函数的示例是:

commonSubstring "XabcdefgY" "abcdefgXY"
> "XY"

commonSubstring "abcdefgXY" "XabcdefgY"
> "abcdefgY"

所以,我已经实现了以下递归,这有点工作:

commonSubstring :: String -> String -> String
commonSubstring first_string second_string 
    | length(second_string)==0=[]
    | take 1 first_string ==take 1 second_string=take 1 first_string ++ commonSubstring (tail first_string)(tail second_string)
    | otherwise=commonSubstring first_string (tail second_string)

问题是:为什么函数不从匹配的正面对返回最终符号?

commonSubstring "abcdefgXY" "XabcdefgY"
>"abcdefg"

commonSubstring "XabcdefgY" "abcdefgXY"
>"X"

【问题讨论】:

  • 您应该使用模式匹配而不是大量的tailtake 1 调用。
  • 你能告诉我,这是如何工作的吗? haskell 令人惊讶.. 对我来说很难,尤其是递归。
  • 已接受任务,但很想知道替代的、更好的实施方法。

标签: haskell recursion


【解决方案1】:

这里有一个提示:

commonSubstring :: String -> String -> String
commonSubstring [] _ = ??
commonSubstring (c:cs) s2 =
  case dropWhile ?? s2 of
    [] -> ??
    d:ds -> ??

如果第一个字符串为空,结果应该是什么?假设第一个字符串至少有一个字符c。您需要考虑两种情况:c 出现在 s2 中,或者没有。如果没有,那么您想跳过c 并继续前进。如果是这样,你想产生c 并继续每个字符串后面的内容。上面的??s可以填写吗?

【讨论】:

    【解决方案2】:

    刚刚想通了,实际上是一个简单但仍然有趣的问题。

       ...
       | length(second_string)==1=take 1 second_string
    

    有没有更正确的方法来返回递归列表的最新元素?

    【讨论】:

    • 你确定这是对的吗?我认为这个练习确实要求你实现一个不同的算法(它很清楚地说明你应该找到一个共同的字符,从两个字符串中删除它,输出它并递归地继续 - 你做了某种移动算法 - 因为一个我认为你失败的例子:尝试反转输入
    • 我认为您的功能与给定的规格不符。你在这里基本上做的是扫描两个字符串。如果字符不匹配,则移动第二个字符串的扫描仪。但这并不总是获得最早的字符。因为第二个字符串的第一个字符可能出现在第一个字符中。
    • 好吧.. 这行得通:commonSubstring :: String -> String -> String commonSubstring first_string second_string |长度(秒字符串)==1=取 1 秒字符串 | take 1 first_string ==take 1 second_string=take 1 first_string ++ commonSubstring (tail first_string)(tail second_string) |否则=commonSubstring first_string (tail second_string)
    猜你喜欢
    • 2016-08-09
    • 2018-08-15
    • 2018-03-10
    • 1970-01-01
    • 2021-12-25
    • 2016-01-25
    • 2013-12-10
    • 2014-12-08
    • 2022-01-07
    相关资源
    最近更新 更多