我有以下问题(Haskell - 函数式编程工艺):
给出函数的定义
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
但是,我认为有更好的方法对其进行分类,但不确定如何。
答案 0 :(得分:7)
怎么样:
howManyEqual a b c
| a == b && b == c = 3
| a /= b && a /= c && b /= c = 0
| otherwise = 2
答案 1 :(得分: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]
答案 2 :(得分:2)
我在想:
howManyEqual a b c
| a == b && b == c = 3
| a == b || b == c || a == c = 2
| otherwise = 0
我不确定它是否比肖恩更好/更差。
由于||
懒惰,我的平均测试次数可能会减少。
答案 3 :(得分: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])
答案 4 :(得分:1)
答案 5 :(得分: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)。