String 在字符串之间交换字符Haskell

String 在字符串之间交换字符Haskell,string,list,haskell,String,List,Haskell,如果我说我有两个字符串或字符列表 list1 = ["c","a","t"] list2 = ["d","o","g"] 如果我使用输入输出“ct”读取字符串并将其传递给函数,函数应该返回“dg” 请把这两个列表联系起来,把这两个列表合并在一起,使用数据.MAP.FABLIST/创建一个查找图,然后在输入字符串上映射并使用映射来找出替换它们的方法。 < P>我首先假设 List1和 List2类型-[Char](即String),因为这是您的文本所显示的内容(您的代码将其命名为[String

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

list1 = ["c","a","t"]
 list2 = ["d","o","g"]
如果我使用输入输出
“ct”
读取字符串并将其传递给函数,函数应该返回
“dg”


请把这两个列表联系起来,把这两个列表合并在一起,使用<代码>数据.MAP.FABLIST/<代码>创建一个查找图,然后在输入字符串上映射并使用映射来找出替换它们的方法。

< P>我首先假设<代码> List1和 List2类型-<代码>[Char](即
String
),因为这是您的文本所显示的内容(您的代码将其命名为
[String]
s——如果您确实需要,请参阅附录中的通用版本)

如果你<代码> zip 这两个列表,你将得到一个指示如何翻译字符的配对列表。在你的例子中,<>代码> zip List1List2= [('c',''),('',' ''),('','g')。我们将此称为查找列表。现在考虑函数:

在我们的情况下,我们可以专门针对

lookup :: Char -> [(Char, Char)] -> Maybe Char
因此,我们有一些东西,它接受一个字符和一个查找列表,如果输入字符在查找列表中,则返回一个替换字符(否则为
Nothing
)。现在我们只需要将我们找到的东西粘在一起:我们本质上需要映射
\c->lookup c lookupList
(更优雅地写为
翻转查找
)覆盖输入字符串,同时抛出查找列表中未找到的任何字符。输入:

这正是我们想要的。现在你的函数可以写成

replace :: String -> String -> String -> String
replace list1 list2 = mapMaybe ((flip lookup) (zip list1 list2))
您需要导入
数据。可能

附录,因为当您理解上述内容时:请注意我们上面所做的与我们处理字符列表的事实无关。我们可以使用任何类型的列表来完成上面的所有操作,这些列表对于等式都是有意义的,例如,对于属于
Eq
typeclass实例的任何类型的列表(参见上面的
lookup
签名)。此外,我们不必将该类型转换为自身类型——例如,上面的每个字符都可以被发送为一个整数!因此,实际上,我们可以编写

replace :: (Eq a) => [a] -> [b] -> [a] -> [b]
replace list1 list2 = mapMaybe ((flip lookup) (zip list1 list2))
现在只要
list1
是一个相等的列表,我们的函数就可以工作。字符替换只是一种特殊情况

一个简单的例子:

> replace "cat" "dog" "ct"
"dg"
> replace "cat" [1,2,3] "ct"
[1,3]

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

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"

哦,我明白了这个逻辑,如果你能提供更多的话,这将是一个巨大的帮助。就像我将从用户那里获取一个字符串的输入,然后我将用我自己的[char]列表转换字符串中的字符。类似于Cesar加密。***表达式:替换***预期类型:Eq a=>[a]->[b]->[a]->[c]***推断类型:Eq a=>[a]->[b]->[a] ->[b]请注意,ivanm的答案(使用
Map
)将比我基于列表的解决方案表现得更好。我故意避免引入(更适合)
映射
数据结构以保持其简单性,但请记住ivanm的解决方案更好。@user1194367:在这里工作很好…您是否尝试将
替换
应用于某个对象?如果是,什么?这只会在替换列表中遍历一次,所以
拍拍“猫”“狗”“ctc”
给出了一个不完整的模式匹配错误,而我认为它应该返回
“dgd”
。有关
查找
数据的详细介绍,请参阅
> replace "cat" "dog" "ct"
"dg"
> replace "cat" [1,2,3] "ct"
[1,3]
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"