在Haskell中计算汉明距离的快速方法

时间:2018-09-11 13:44:54

标签: haskell

给定两个字符串,在haskell中计算汉明距离的快速方法是什么。

例如,示例输入:

GGGCCGTTGGTGGACCGTTGAC

输出:

3

1 个答案:

答案 0 :(得分:3)

给定类型是Eq类型类的实例,我们可以计算具有相同类型的两个列表(长度相等)的汉明距离,

hammingDistance :: Eq a => [a] -> [a] -> Int
hammingDistance = (sum .) . zipWith ((fromEnum .) . (/=))

或其他选择:

hammingDistance :: Eq a => [a] -> [a] -> Int
hammingDistance la lb = length (filter id (zipWith (/=) la lb))

例如:

Prelude> hammingDistance "GGGCCGTTGGT" "GGACCGTTGAC"
3

这两个函数或多或少以类似的方式工作:我们同时枚举两个列表,对于两个元素,我们检查两个元素是否不相等。然后,我们计算不相等的元素数。

使其更加安全

由于可以使用长度不同的两个列表来调用上述函数,因此最好更改它并添加一些检查,就像@JonPurdy建议的那样。例如,我们可以实现带有签名的功能:

hammingDistance :: Eq a => [a] -> [a] -> Maybe Int

如果两个列表的长度不同,我们在这里返回NothingJust x(两个列表的汉明距离为x)。例如,我们可以使用递归来编写它:

hammingDistance :: Eq a => [a] -> [a] -> Int
hammingDistance (x:xs) (y:ys) | x /= y = fmap (+1) tl
                              | otherwise = tl
    where tl = hammingDistance xs ys
hammingDistance [] [] = Just 0
hammingDistance _ _ = Nothing