如何在String(Haskell)中同时替换多个元素

时间:2013-05-05 10:03:52

标签: string list haskell replace

我想以2个列表为例;

find=["Hou","House","Mouse"]
repl=["Mou","Bird","House"]

所以当我给出这样的文字时;

"The House with Mouse is big"

输出应为此;

"The Mouse with House is big"

所以我写了这个;

replace :: String->String->String->String
replace _ _ []=[]

replace find repl text
  = if take(length find) text == find
      then repl ++ replace find repl (drop (length find) text)
      else [head text] ++ (replace find repl (tail text))

replaceMore ::[String]->[String]->String->String
replaceMore _ _ []=[]
replaceMore _ [] _ =[]
replaceMore [] _ _ =[]
replaceMore find repl text
  = if (tail find) == [] || (tail repl)==[]
      then text
      else replaceMore (tail find)
                       (tail repl)
                       (replace (head find) (head repl) text)

返回

"The Mouse with Mouse is big"

所以它不像我想要的那样工作,我认为问题就在这里;

replaceMore _ _ []=[]
replaceMore _ [] _ =[]
replaceMore [] _ _ =[]

但我仍然不知道如何解决这个问题。任何想法?

2 个答案:

答案 0 :(得分:2)

我可能会给你一些关于工作算法的想法。

首先,您需要根据String字符串将输入[String]划分为部分(find)。所以这个功能是

divideIntoParts :: [String] -> String -> [String]

有点像

divideIntoParts find "The House with Mouse is big"

给出

["The ", "Hou", "se with ", "Mouse", " is big"]

因此,它从字符串中提取要替换的部分,但通过将其他部分保留在同一列表中来保留字母的顺序。天真的实现可能看起来像这样

https://gist.github.com/Shekeen/5523749

接下来,您需要一个功能来扫描此列表并更换需要更换的部件。签名将是

replaceParts :: [String] -> [String] -> [String] -> String

就像

一样
replaceParts find repl $ divideIntoParts find "The House with Mouse is big"

将是

"The Mouse with House is big"

所以你的完整replace函数看起来像

replacePatterns :: [String] -> [String] -> String -> String
replacePatterns find repl = (replaceParts find repl) . (divideIntoParts find)

另外,您确实需要实现更快的子字符串搜索算法,并考虑将findrepl替换为Data.Map

答案 1 :(得分:0)

我可以看到两个错误:

  1. findrepl的最终元素始终被忽略。在replaceMoretext时,tail find == []会返回tail repl == [];这应该是find == []repl == []

    但他们应该被早期的等式

    抓住
    replaceMore _ [] _ =[]
    replaceMore [] _ _ =[]
    

    ,你现在应该能看到,是错的,应该是

    replaceMore _ [] text = text
    replaceMore [] _ text = text
    
  2. 但输出将是

    "The House with House is big"
    

    还是错的。这是因为您正在构建replaceMore replace。对于每个搜索词,您搜索文本,找到后将其替换。因此,您将"Hou"替换为"Mou"(因此"House"替换为"Mouse");然后您将"Mouse"替换为"House"(意味着原来"House"最终会再次为"House"。)

    相反,您应该搜索一次文本,在推进文本之前查找某个位置的每个搜索字词。