3

是否可以创建一个函数来创建一个带有列表输入的集合。

如果不使用递归,我想不出任何办法。

我可以使用高阶函数,如折叠、过滤、映射、压缩。我只是不能在我的函数中进行递归。

显然我不能使用 nub。

我一直在努力想弄清楚如何在没有递归或任何类型的循环的情况下摆脱重复项(至少我认为我们不能使用循环,会问)。

4

4 回答 4

10

一种方法:

  1. 对列表进行排序。
  2. 用尾部压缩列表(例如[1,1,2,3]变成[(1,1),(1,2),(2,3)]
  3. 删除两个项目相同的所有对。
  4. 返回包含排序列表的第一个元素的列表,然后是压缩列表中每对的第二项。

在代码中:

import Data.List

setify [] = []
setify xs = x : map snd (filter (uncurry (/=)) (zip sxs (tail sxs)))
    where sxs = sort xs
          x   = head sxs
于 2010-09-25T21:12:05.853 回答
4

另一种方法是使用折叠来累积值以及成员资格检查(如果以前曾见过)。

setify :: (Eq b) => [b] -> [b]
setify = foldl f []
where f acc next | next `elem` acc = acc 
                 | otherwise       = next:acc

不是最快的方法,但它可以完成工作。

于 2010-09-25T22:57:18.177 回答
0

你可以使用分组方法吗?如果是这样,那么您可以对列表进行排序,将它们分组,最后从每个组中取出 1 个项目。

import Data.List

setify :: Eq a => [a] -> [a]
setify = map head . group . sort
于 2020-01-15T12:28:26.353 回答
-1

为什么所有复杂(而且错误!)的解决方案?只需这样做:

uniq [] = []
uniq (x:xs)= x:(uniq (filter (/=x) xs))

setify xs = uniq $ sort xs -- If you want to sort too.

它从列表的尾部过滤每个元素。简单的。

于 2011-11-27T18:50:58.350 回答