2010-09-25 71 views
3

是否可以創建一個函數,它將創建一個列表輸入的集合。Haskell - 創建集(獨特的排序列表) - 沒有遞歸,沒有結節

我只是想不到任何方式沒有使用遞歸。

我可以使用摺疊,過濾器,地圖,zip等高階函數。我不能在我的函數中遞歸。

顯然我不能使用nub。

我一直在敲我的頭,試圖找出如何擺脫重複沒有遞歸或任何類型的循環(至少我不認爲我們可以使用循環,會問)。

+1

'nubBy(==)'。那不是'nub'吧? :p:p – kennytm 2010-09-27 09:21:51

回答

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 
+0

從來沒有想到過。 – Matt 2010-09-25 21:32:36

+4

你可能不應該給代碼,只是方法,因爲這是作業... – alternative 2010-09-26 20:36:30

+0

但它不工作,但!想一想/試一下當列表的第一個元素是最大的時候會發生什麼... – yatima2975 2010-09-27 09:07:35

4

另一個辦法是使用摺疊如果以前已經見過累積值與會員一起檢查。

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

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

-2

爲什麼所有的複雜(和錯誤的!)解決方案?只要這樣做:

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

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

它從列表的尾部過濾每個元素。簡單。

+3

這是一個遞歸解決方案。 OP有明確的要求不使用遞歸。 – hammar 2011-11-27 19:04:23

+2

這是Haskell。只有遞歸。 這裏的每一個答案都使用遞歸(至少在內部排序和foldl。) 並且:如果你想做Haskell沒有遞歸... *你做錯了*。 – Evi1M4chine 2012-04-10 23:14:44