給出一個列表,我想用「邊界函數」將它分成多個簇。這樣的功能將需要兩個連續的列表元素並決定它們是否應該屬於同一個集羣。使用邊界函數對列表進行聚類
所以基本上,我想是這樣的:
clusterBy :: (a -> a -> Bool) -> [a] -> [[a]]
ghci> farAway x y = abs (x - y) > 10
ghci> clusterBy farAway [1, 4, 18, 23, 1, 17, 21, 12, 30, 39, 48]
[[1, 4], [18, 23], [1], [17, 21, 12], [30, 39, 48]]
仰望它Hoogle這種類型的聲明只產生groupBy
這不是我所需要的東西(它沒有考慮要素的順序考慮)。
是否有任何類似的庫函數?或者,也可以:它如何能夠乾淨地實施,即不採用尾遞歸循環?
編輯:作爲參考,我設法編造實行的是以下幾點:
clusterBy :: (a -> a -> Bool) -> [a] -> [[a]]
clusterBy isBoundary list =
loop list [] []
where
loop (first:rest) [] result = loop rest [first] result
loop [email protected](next:rest) cluster result =
if isBoundary (head cluster) next then
loop list [] ((reverse cluster):result)
else
loop rest (next:cluster) result
loop [] [email protected](_:_) result = cluster:result
loop _ _ result = result
爲什麼尾部遞歸循環不乾淨?避免這種直接解決方案的目的是什麼? – 2011-12-27 18:09:02
我編輯了這個問題,添加了我設法提出的尾遞歸版本。我對終端條件的數量和總體冗長度感到不滿。坦率地說,它看起來並沒有什麼特別的 - 它基本上是一個迫切需要的功能語言版本。 – Xion 2011-12-27 18:30:22