Haskell如何根据第一个和第二个字符比较两个字符串之间的匹配?

时间:2017-08-26 00:49:33

标签: list haskell

很抱歉提出一个微不足道的问题,我是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个As,每个在列表中出现一次,所以第一个Int将返回2

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

  

通过比较列表a和列表b,[" B3"," A1"]中的元素和b中的元素[" C1",&# 34; A3"],1在列表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,String返回应该是[" C1"," A3," A6"],可能,我想用这些结果来我计算的第二个Int, 但我不知道如何修复此代码以产生正确的答案,

我可以将两个代码组合在一起,如

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

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您的问题分为两部分。第一部分看起来很简单:你有一个两个字符串的列表,你想要对第一个字符进行一些比较,然后对第二个字符进行一些比较。

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

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

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

现在你有两个单独的列表。如何“比较”两个列表中的字符?这部分似乎更复杂,因为你想要实现的目标对我来说并不清楚。

这是一个提议:1。计算两个列表中每个字符的数量,2。对于两个列表中存在的每个字符,保留两个列表中字符存在的次数,即最小值两个列表中该char的计数。一个示例将更容易取消:如果第一个列表中有三个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如果密钥出现一次,With (+)如果出现两次,依此类推):这是适用于1对的b部分。< / p>

对于列表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

Prelude Data.Map> Data.Map.foldl(+)0(g a b) 2 仅保留两个列表中存在的密钥。 lambda函数占用最少的计数,并将其指定为该键的值。

最后,您只需计算结果地图的值的总和:

foldl

last得到值的总和。

您只需重复数字处理(使用plan())。