2

我有一个高阶函数,它需要:

results ["Red", "Blue", "Green", "Blue", "Blue", "Red"]

并返回:

[(1,"Green"),(2,"Red"),(3,"Blue")]

我需要使用结果函数并创建一个名为winner的新函数:

winner :: [Party ] -> Party
winner xs = 

这将输出最常出现的颜色并删除元组中的第一个元素,如果两种颜色具有相同的出现次数,它将输出两种颜色,例如:

winner ["Red", "Blue", "Green", "Blue", "Blue", "Red"]

输出:

"blue"

到目前为止,我已经尝试使用 snd 和 tail,但我不断收到错误。先感谢您。

4

4 回答 4

10

如果你有这个results功能,一个简单的应用

maximumBy :: (a -> a -> Ordering) -> [a] -> a

就足够了

import Data.List -- for maximumBy
import Data.Ord  -- for comparing

winner = snd . maximumBy (comparing fst) . results

看见

如果两种颜色出现相同,则输出两种颜色

您需要不同的类型 - 当然还有不同的实现,但使用库函数仍然很容易:

import Data.List
import Data.Ord
import Data.Function

winners :: [Party] -> [Party]
winners = map snd . head . groupBy ((==) `on` fst) . sortBy (flip $ comparing fst) . results

由于results已经生成了一个排序列表——我不想仅仅从示例输出中依赖它——没有必要再次排序,我们可以使用

winners = map snd . last . groupBy ((==) `on` fst) . results

生成所有最常出现的元素的列表。如果只需要一个最频繁的元素,则可以通过

winner = snd . last . results

从排序的频率列表中。

于 2012-04-16T21:32:10.917 回答
5
import Data.List
import Data.Ord
winner xs = head . maximumBy (comparing length) . group . sort $ xs
main = print  $ winner ["Red", "Blue", "Green", "Blue", "Blue", "Red"]

看起来是最直接的方式。

于 2012-04-17T00:27:37.253 回答
3

如果要避免排序,可以使用具有功能的MultiSetfinMax

于 2012-04-17T06:45:35.617 回答
1

winners函数中,您会得到 的列表String,然后您可以通过应用该results函数将其转换为 '(Int, String)' 元组的列表。然后,您想要获取这些元组中的最后一个(假设results以出现次数的升序返回元素)并返回该元组的第二个元素。您已经提到您已经尝试过该snd功能,所以唯一的麻烦是中间步骤,获取元组列表的最后一个元素,对吗?

返回最后一个元素的函数的类型应该是什么?它接受一个(Int, String)元组列表并返回一个元组,因此对类型的猜测可能是[(Int, String)] -> (Int, String),但该函数并不需要知道它正在处理列表中的元组。它只需要返回列表的最后一个元素,因此更好的类型可能是[a] -> a. 有了这种类型,去Hoogle并在搜索框中输入它,你就会得到你需要的功能作为第二个结果。

对于只返回单个结果的获胜者函数,这应该足够了。如果您希望能够返回多个结果,那么 - 正如 Daniel Fischer 在他的回答中指出的那样 - 您需要另一个签名和稍微复杂的实现。我认为最简单的方法是通过过滤掉那些没有出现最大次数的元组来找到与最后一个元组具有相同出现次数的所有元组(再次假设出现的升序),然后转换结果元组列表到这些元组的第二个元素的列表,通过映射snd列表:

winners :: [String] -> [String]
winners xs = map snd maxOccursTuples
    where maxOccursTuples = filter isMaxOccursTuple occurrences
          isMaxOccursTuple tuple = fst tuple == maxOccurs
          maxOccurs = fst (last occurrences)
          occurrences = results xs
于 2012-04-16T22:11:39.307 回答