交换字符串之间的字符Haskell

时间:2012-02-07 10:17:54

标签: string list haskell

如果我说我有两个字符串或字符列表,

list1 = ["c","a","t"]
 list2 = ["d","o","g"]

如果我使用输入输出"ct"读取字符串并将其传递给函数,则该函数应返回"dg"

请告诉我有关此类功能的任何想法。

3 个答案:

答案 0 :(得分:5)

我会考虑使用这两个列表,将它们压缩在一起,使用Data.Map.fromList创建一个查找Map,然后映射输入String并使用Map来计算替换它们的内容。

答案 1 :(得分:3)

我首先假设list1list2[Char]类型(即String),因为这就是您的文字似乎表明的内容(您的代码将其作为{ {1}} s - 如果你真的想要这个,请参阅附录中的通用版本。)

如果您[String]这两个列表,最终会得到一对指示如何翻译字符的对。在您的示例中,zip。我们将此称为查找列表。现在考虑函数lookup

zip list1 list2 = [('c','d'), ('a','o'), ('t','g')]

在我们的案例中,我们可以将其专门化为

lookup :: Eq a => a -> [(a, b)] -> Maybe b

所以我们有一些东西需要一个字符和一个查找列表,如果输入字符在查找列表中,则返回一个替换字符(否则为lookup :: Char -> [(Char, Char)] -> Maybe Char )。现在我们只需要粘合我们一起找到的东西:我们基本上需要在输入字符串上映射Nothing(更优雅地写为\c -> lookup c lookupList),而抛出任意在查找列表中找不到的字符。好吧,输入mapMaybe

flip lookup

它完全符合我们的要求。现在你的函数可以写成

mapMaybe :: (a -> Maybe b) -> [a] -> [b]

您需要导入replace :: String -> String -> String -> String replace list1 list2 = mapMaybe ((flip lookup) (zip list1 list2))

附录,因为当您理解上述内容时:观察我们上面所做的与我们使用字符列表这一事实无关。我们可以使用任何类型的列表执行上述所有操作,其中等式是有意义的,即(列表)任何类型的Data.Maybe类型类的实例(参见{{1的签名) 1}}以上)。而且,我们不必从该类型转换为自身 - 例如,上面的每个字符都可以发送一个整数!所以,我们可以写

Eq

现在只要lookup是一个有平等意义的东西的列表,我们的函数就可以工作。替换字符只是一种特殊情况。

一个简单的例子:

replace :: (Eq a) => [a] -> [b] -> [a] -> [b]
replace list1 list2 = mapMaybe ((flip lookup) (zip list1 list2))

答案 2 :(得分:0)

对于两个字符串,您可以执行以下操作:

patt :: String -> String -> String -> String
patt (x : xs) (y : ys) p'@(p : ps)
  | p == x = y : patt xs ys ps
  | otherwise = patt xs ys p'
patt _ _ [] = []

main :: IO ()
main = do
  putStrLn $ patt "cat" "dog" "ct"