哈斯克尔 如何根据第一个和第二个字符比较两个字符串之间的出现?



很抱歉问了一个微不足道的问题,我是Haskell编程的新手, 我在两个字符串之间的比较中挣扎

这两个列表是

a :: [String]
a = ["A2","B3","A1"]
b::[String]
b= ["C1","A3,"A6"]

我想根据第一个字符和第二个字符比较相同的部分并返回两个 Int,即 (2,2( 因为有 2 个字符串,第一个字符是相同的,基于列表 b,即 2 由于两者都存在于两个列表中,基于比较,

list a ["A2","A1"]

list b["A3","A6"]

基于列表 b,有 2 个 A,每个在列表 A 中出现一次,因此第一个 Int 将返回 2

而第二个Int来自于基于列表b的第二个字符之间的比较,概念与第一个Int基本相同,

通过比较列表 A 和列表 B、A ["B3","A1"] 中的元素

和 B ["C1","A3"] 中的元素,列表 A 中出现一次,增量 1 并忽略,列表 A 中出现 3,增量,返回为 2

最终回报将是 (2,2( 我的成就是: 我试图使用两个函数返回两个 Int,我的第一个函数是这样的: 它返回第一个 Int

byCompare ::[String]->[String] -> (Int,[String])  
byCompare [] x = (0, x)
byCompare x [] = (0, [])    
byCompare (x:xs)(y:ys)
| comparehead x y == True =  increment (byCompare xs ys)
| otherwise = append y (byCompare [x] ys) 
where 
increment (count, results) = (count + 1,results)
append y (count, results) = (count, y:results)
comparehead a b 
| head a == head b = True
| otherwise = False

返回字符串是我想弄清楚我的代码发生了什么,它返回我一个错误的答案(1,["C1","A6"](所需的 Int 返回应该是 2,字符串返回应该是 ["C1","A3,"A6"],可能,我想使用这些结果来计算第二个 Int, 但我不知道如何修复此代码以产生正确答案,

我可以像这样将两个代码组合在一起吗

bigCombine ::[String] ->[String] ->(Int,Int)?

非常感谢您的帮助!

你的问题有两个部分。第一部分似乎很简单:你有一个包含两个字符的字符串列表,你想对第一个字符进行一些比较,然后在第二个字符上进行一些比较。

您只需要隔离第一个字符和第二个字符:

Prelude> a = ["A2","B3","A1"]
Prelude> head<$>a
"ABA"
Prelude> last<$>a
"231"

<$>fmap运算符:函数(headlast(应用于列表a的每个元素。

现在您有两个单独的列表。如何"比较"两个列表中的字符?这部分似乎更复杂,因为我不清楚您要实现的目标。

这里有一个建议:1.计算两个列表中每个字符的数量,2.对于两个列表中存在的每个字符,保留该字符在两个列表中出现的次数,即两个列表中该字符计数的最小值。一个例子会更容易取消:如果你在第一个列表中有三个A,在第二个列表中有两个,你保留两个作为A的值。

要获取每个字符的计数,您可以使用关联数组(或"哈希映射"(:

Prelude> import Data.Map
Prelude Data.Map> f l = fromListWith (+) [(x, 1) | x <-head<$>l]
Prelude Data.Map> f a
fromList [('A',2),('B',1)]

你认得head<$>a:它只是a中第一个字符的列表,即"ABA"(=['A', 'B', 'A'](。现在,您将使用数组的元素作为键构建一个关联数组。这些值计算为每个键存在的次数。(1如果键出现一次,1 + 1如果出现两次,依此类推(:这是适用于对1With (+)部分。

对于列表b,您有:

Prelude Data.Map> b = ["C1","A3","A6"]
Prelude Data.Map> f b
fromList [('A',2),('C',1)]

是时候比较两个关联数组了。

Prelude Data.Map> g l1 l2 = intersectionWithKey(c n1 n2->min n1 n2)(f l1)(f l2)
Prelude Data.Map> g a b
fromList [('A',2)]

intersectionWithKey仅保留两个列表中存在的键。lambda 函数采用最少的计数并将其分配为该键的值。

最后,您只需要计算结果映射的值的总和:

Prelude Data.Map> Data.Map.foldl(+)0(g a b)
2

foldl使值的总和。

您只需要对数字重复该过程(使用last(。

最新更新