【问题标题】:Taking a list of strings and replacing multiple words with one获取字符串列表并用一个替换多个单词
【发布时间】:2014-02-20 16:10:55
【问题描述】:

我对 Haskell 很陌生,作为输入,我想将一个字符串数组作为 ["HEY" "I'LL" "BE" "RIGHT" "BACK"] 并寻找让我们说"BE" "RIGHT" "BACK" 并用不同的词替换它,让我们说"CHEESE"。我有一个为单个单词制作的函数,但如果字符串包含某个短语以用单词替换它,我希望它能够工作。哦,我不想使用外部库。

代码:

replace :: [String] -> [String]
replace [] = []
replace (h:t)
    | h == "WORD" = "REPLACED" : replace t
    | otherwise = h : replace t

【问题讨论】:

  • 那么替换单个单词的代码是什么?这将有助于为多个单词执行它。
  • 好的,我会编辑原帖
  • 那么您将如何修改您的replace 函数,使其具有类型签名replace :: String -> String -> [String] -> [String],以便您可以传入要搜索的值和要替换的值?类似replace old new (h:t) = ...
  • 它不一定要按照我逐行执行的方式。我只需要一个想法或提示可以这么说。因为我可以做 4 个声明,但我不知道该怎么做
  • 你试过elem功能吗?它测试一个元素是否在列表中。

标签: string list haskell recursion


【解决方案1】:

你现在拥有的也可以实现为

replace ("WORD":rest) = "REPLACED" : replace rest
replace (x:rest) = x : replace rest
replace [] = []

这可以扩展到您的示例

replace ("BE":"RIGHT":"BACK":rest) = "CHEESE" : replace rest
replace (x:rest) = x : replace rest
replace [] = []

但显然这不是一个好方法。我们想要一个更通用的解决方案,我们可以传入一个短语(或子列表)来替换。首先,我们知道以下几点:

  1. 输入是n 元素的列表(递归时递减)
  2. 短语是m 元素的列表(在我们递归时保持不变)
  3. 如果m > n,我们肯定没有匹配项
  4. 如果m <= n,我们可能会匹配
  5. 如果我们没有匹配,请保留头部并尝试使用尾部

虽然有更有效的算法,但一个简单的算法是检查列表中每一步的长度。这可以很简单地完成

--             Phrase    Replacement  Sentence   New sentence
replaceMany :: [String] -> String -> [String] -> [String]
replaceMany phrase new sentence = go sentence
    where
        phraseLen = length phrase
        go []   = []
        go sent@(x:xs)
            | sentLen < phraseLen = sent
            | first == phrase     = new : go rest
            | otherwise           = x : go xs
            where
                sentLen = length sent
                first   = take phraseLen sent
                rest    = drop phraseLen sent

在这里,我们可以利用 Haskell 的懒惰,继续定义 firstrest,而不用担心这样做是否有效。如果不使用它们,它们永远不会被计算。我还选择使用sent@(x:xs) 形式的更复杂的模式匹配。这匹配至少有一个元素的列表,将整个列表分配给sent,将第一个元素分配给x,将列表的尾部分配给xs。接下来,我们只检查每个条件。如果sentLen &lt; phraseLen,则列表的其余部分不可能有匹配项,因此只需返回整个内容。如果第一个m元素等于我们的短语,则替换它并继续搜索,否则只需放回第一个元素并继续搜索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2021-05-22
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 2021-06-12
    相关资源
    最近更新 更多