4

我有以下问题(Haskell - The Craft of Functional Programming):

给出函数的定义

howManyEqua1 :: Int -> Int -> Int -> Int

它返回它的三个参数中有多少是相等的,所以

howManyEqua1 :: 34 25 36 = 0
howManyEqual :: 34 25 34 = 2
howManyEqual :: 34 34 34 = 3

我给出的答案是:

howManyEqual :: Int -> Int -> Int -> Int
howManyEqual    a      b      c
    | a == b && b == c            = 3
    | a == b                      = 2
    | b == c                      = 2
    | a == c                      = 2
    | otherwise                   = 0

但是,我相信有更好的分类方法,但不确定如何分类。

4

6 回答 6

8

怎么样:

howManyEqual a b c
    | a == b && b == c           = 3
    | a /= b && a /= c && b /= c = 0
    | otherwise                  = 2
于 2011-05-13T05:28:46.263 回答
5

或者:

howManyEqual a b c = case length.nub $ [a,b,c] of
    1 -> 3
    2 -> 2
    3 -> 0

更新:

使用 ryaner 的答案作为起点和 luqui 的泛化定义,我们也可以使用这一行并获得具有 O(n log n) 复杂度的通用解决方案。:

howManyEqualG = sum.filter (>1).map length.group.sort
-- Now, specialized to three:
howManyEqual a b c = howManyEqualG [a,b,c]
于 2011-05-13T05:37:10.413 回答
2

我在想:

howManyEqual a b c
  | a == b && b == c           = 3
  | a == b || b == c || a == c = 2
  | otherwise                  = 0

我不确定它是否比肖恩的更好/更差。

由于||懒惰,我的平均测试可能会更少。

于 2011-05-13T05:34:41.420 回答
2

有点搞笑的解决方案:

howManyEqual a b c = [0,2,42,3] !! (length $ filter id [a == b, b == c, a == c])

[编辑]

更短:

import Data.List
howManyEqual a b c = [42,3,2,0] !! (length $ nub [a,b,c])
于 2011-05-13T07:36:53.343 回答
1

这是任何n的解决方案。

于 2011-05-13T05:53:11.613 回答
1

我能想到的一个可以避免警卫的衬里:

import Data.List

howManyEqual :: Int -> Int -> Int -> Int
howManyEqual a b c      = maximum $ 0 : (filter (> 1) . map length . group . sort) [a,b,c]

不过,这显然效率较低,并且似乎是对函数组合使用的过度杀伤。

如果您的输入是一个巨大的列表,那么使用这样的算法可能才有意义,您想计算有多少元素是最多相等的。这是 O(n log n)。

于 2011-05-13T05:54:06.947 回答