【问题标题】:Haskell - The Craft of Functional Programming (exercise 4.3)Haskell - 函数式编程的技巧(练习 4.3)
【发布时间】:2011-08-24 15:27:33
【问题描述】:

我有以下问题(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

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

【问题讨论】:

  • 为什么我还没有任何答案?
  • Stack Overflow 不是独角兽。如果他们愿意,人们会回答。 :)
  • ...但是当独角兽出现时,他们会带着气球。太棒了。

标签: haskell programming-languages equals guard


【解决方案1】:

怎么样:

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

【讨论】:

  • 但是如果只有一个词是相等的呢?
【解决方案2】:

或者:

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]

【讨论】:

  • 你打败了我。我正要发布完全相同的东西!这是非正统但有趣的选择。
  • 对于我需要知道的内容似乎有点偏离轨道,不过感谢您的回答!
  • 不知道为什么会得到-1。它是唯一一个为 n 参数提供通用解决方案的方法。 +1
  • 我喜欢它,但我不明白这会如何概括。它甚至不清楚一般问题是什么:howManyEqualN [1,1,1,2,2,3] 等于 5、3,什么?
  • @jon_darkstar 感谢@luqui 和@ryaner,我们现在有了一个使用howManyEqualN [1,1,1,2,2,3] == 5 的通用版本,根据luqui 的链接定义。
【解决方案3】:

我在想:

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

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

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

【讨论】:

    【解决方案4】:

    有点搞笑的解决办法:

    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])
    

    【讨论】:

    • 有趣且富有创意。我喜欢它:)
    【解决方案5】:

    【讨论】:

      【解决方案6】:

      我能想到的一种可以避开警卫的单线:

      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)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-01
        • 2011-02-22
        相关资源
        最近更新 更多