Haskell中max函数的意外问题

时间:2017-10-25 07:40:47

标签: list function haskell recursion max

我有这个功能,删除列表的最大值,它似乎工作,当我不断添加数字,它一直有效,直到我添加一个新的高数字。然后它仍然只删除旧的最大数字。但是当我开始一个新的列表时,它将再次起作用。任何人都可以解释发生了什么,以及我做错了什么?

    removeMax :: [Int] -> [Int]
    removeMax [] = []
    removeMax [x] = [] 
    removeMax (x:y:xs)
        | x > y = (y:xs)
        | otherwise = x : removeMax (y:xs)

以下是我做过的几项测试的结果:

    *Main> removeMax [1,9,3,2,6]
    [1,3,2,6]
    *Main> removeMax [1,9,3,2,6,8]
    [1,3,2,6,8]
    *Main> removeMax [1,9,3,2,6,8,7]
    [1,3,2,6,8,7]
    *Main> removeMax [1,9,3,2,6,8,7,14]
    [1,3,2,6,8,7,14]
    *Main> removeMax [1,9,3,2,6,8,7,14]
    [1,3,2,6,8,7,14]
    *Main> removeMax [1,9,3,2,6,8,7,14]
    [1,3,2,6,8,7,14]
    *Main> removeMax [1,3,14,5]
    [1,3,5]
    *Main> removeMax[1,3,8,9]
    [1,3,8]
    *Main> removeMax [1,2,3,67,87,12]
    [1,2,3,67,12]
    *Main> removeMax [1,2,3,67,87,12,88]
    [1,2,3,67,12,88]

正如您所看到的那样,当您继续在新列表上执行此操作并使用旧列表并仅添加较小的数字时,它可以正常工作。

1 个答案:

答案 0 :(得分:0)

您的功能行为方式并不奇怪 - 您将其定义为删除大于其后续数字的第一个数字

要真正删除给定列表中的最大值,最简单的方法是:

  • 通过扫描整个列表找到最大值
  • 将其删除

使用两个辅助函数,这种方法的实现非常简单:

  findMax: [Int] -> Int
  removeElement: [Int] -> Int -> [Int]

但是,您还应该考虑边缘情况:

  • 如果最大值出现多次,会发生什么?即应该removeMax [1, 3, 2, 3]返回[1,2,3][1,2]还是[1,3,2]?
  • 您的新实现是否正确处理空列表? (你现在的那个)