你现在也可以实现什么作为
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 [] = []
但显然这不是写它的一个好方法。我们希望有一个更通用的解决方案,我们可以通过一个短语(或子列表)来替换。首先,我们知道以下几点:
- 输入是
n
元素的列表(减少为我们递归)
- 这句
m
元素的列表(保持不变,因为我们递归)
- 如果
m > n
,我们绝对没有匹配
- 如果,我们可能有一个匹配
- 如果我们没有比赛,保持头部与尾部尝试
虽然这里有更高效的算法,但一个简单的算法是检查我们沿着列表的每一步的长度。这可以倒也干脆做的
-- Phrase Replacement Sentence New sentence
replaceMany :: [String] -> String -> [String] -> [String]
replaceMany phrase new sentence = go sentence
where
phraseLen = length phrase
go [] = []
go [email protected](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的懒惰的优势,先走一步,定义first
和rest
,不用担心,如果它是有效的这样做。如果他们没有使用,他们从来没有得到计算。我选择以[email protected](x:xs)
的形式使用一些更复杂的模式匹配。这与包含至少一个元素的列表匹配,将整个列表分配给sent
,将第一个元素分配给x
,将列表的尾部分配给xs
。接下来,我们只是检查每个条件。如果sentLen < phraseLen
,那么就不可能在列表的其余部分找到一个匹配项,所以只需返回整个项目。如果第一个m
元素等于我们的短语,那么替换它并继续搜索,否则只需放回第一个元素并继续搜索。
那么你的代码替换一个单词是什么?这将有助于执行多个单词。 – bheklilr
好吧我将编辑原文 – Zeusftw
所以,如何修改'replace'函数,使其具有类型签名'replace :: String - > String - > [String] - > [String]',以便您可以传递在你想要搜索的值和你想要替换的值中?就像'替换旧的新的(h:t)= ...' – bheklilr