繁体   English   中英

Haskell:从x元素列表中创建唯一的n元组

[英]Haskell: Create unique n-tuples from a list of x elements

我有一个x元素列表,我希望从中获得所有可能的唯一n元组。

所以我基本上是在寻找实现

nub . map (take n) . permutations

不必创建重复项。

对我来说,这看起来像一个很可能已经在某个地方定义的函数。

是这样吗

你的意思是这样吗?

import Data.List (permutations)

choose n list = concatMap permutations $ choose' list [] where
  choose' []     r = if length r == n then [r] else []
  choose' (x:xs) r | length r == n = [r]
                   | otherwise     = choose' xs (x:r) 
                                  ++ choose' xs r

输出:

*Main> choose 2 [0..5]
[[1,0],[0,1],[2,0],[0,2],[3,0],[0,3],[4,0],[0,4],[5,0],[0,5],[2,1]
,[1,2],[3,1],[1,3],[4,1],[1,4],[5,1],[1,5],[3,2],[2,3],[4,2],[2,4]
,[5,2],[2,5],[4,3],[3,4],[5,3],[3,5],[5,4],[4,5]]

Hayoo对于查找功能非常有帮助。 通过这个查询 ,我找到了置换包,尽管我没有详细研究实现,但它似乎可以满足您的要求。

但是,使用此处在堆栈溢出中讨论的解决方案之一可能会更简单。 搜索后发现了一些相关的帖子。 您可能会看一下有关 Data.List中permutations功能实现的讨论 ,并对其进行修改以满足您的需求。

既然您已请求元组,那么以下是利用列表是应用函子的事实的解决方案:

Prelude> let list = [0..4]
Prelude> import Control.Applicative
Prelude Control.Applicative> (,) <$> list <*> list
[(0,0),(0,1),(0,2),(0,3),(0,4),(1,0),(1,1),(1,2),...
Prelude Control.Applicative> (,,) <$> list <*> list <*> list
[(0,0,0),(0,0,1),(0,0,2),(0,0,3),(0,0,4),(0,1,0),(0,1,1),...

但是,由于定义不同类型的元组的类型不同,因此不可能编写一个通用函数,该函数将基于某个n参数产生不同类型的结果。

虽然我必须指出,可以通过使用一些高级类型级编程技术来解决此问题,方法是为代表您要支持的元组的元组引入类型级自然类型的类型类和实例,但是我敢肯定这会过分。 此外,利用自然类型也将是多余的,因为所有必需的信息都可以从结果类型中确定,因此,一个简单的类型类和您要支持的所有元组的实例就足够了。

您可以使用Math.Combinatorics.Multisetcabal install multiset-comb ),即使输入列表中存在重复项,也可以避免输出列表中存在重复项:

import Math.Combinatorics.Multiset  (fromList, kSubsets, permutations)

permute :: Ord a => Int -> [a] -> [[a]]
permute n = concatMap permutations . kSubsets n . fromList

main = print $ permute 2 [1, 1, 2, 3]

生产:

[[2,3],[3,2],[1,3],[3,1],[1,2],[2,1],[1,1]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM